Misc VFS2 fixes
- Fix defer operation ordering in kernfs.Filesystem.AccessAt() - Add AT_NULL entry in proc/pid/auvx - Fix line padding in /proc/pid/maps - Fix linux_dirent serialization for getdents(2) - Remove file creation flags from vfs.FileDescription.statusFlags() Updates #1193, #1035 PiperOrigin-RevId: 307704159
This commit is contained in:
parent
eba086642e
commit
37e01fd2ea
|
@ -73,8 +73,7 @@ func checkTaskState(t *kernel.Task) error {
|
||||||
type taskDir struct {
|
type taskDir struct {
|
||||||
ramfs.Dir
|
ramfs.Dir
|
||||||
|
|
||||||
t *kernel.Task
|
t *kernel.Task
|
||||||
pidns *kernel.PIDNamespace
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ fs.InodeOperations = (*taskDir)(nil)
|
var _ fs.InodeOperations = (*taskDir)(nil)
|
||||||
|
|
|
@ -246,8 +246,8 @@ func (fs *Filesystem) Sync(ctx context.Context) error {
|
||||||
// AccessAt implements vfs.Filesystem.Impl.AccessAt.
|
// AccessAt implements vfs.Filesystem.Impl.AccessAt.
|
||||||
func (fs *Filesystem) AccessAt(ctx context.Context, rp *vfs.ResolvingPath, creds *auth.Credentials, ats vfs.AccessTypes) error {
|
func (fs *Filesystem) AccessAt(ctx context.Context, rp *vfs.ResolvingPath, creds *auth.Credentials, ats vfs.AccessTypes) error {
|
||||||
fs.mu.RLock()
|
fs.mu.RLock()
|
||||||
defer fs.mu.RUnlock()
|
|
||||||
defer fs.processDeferredDecRefs()
|
defer fs.processDeferredDecRefs()
|
||||||
|
defer fs.mu.RUnlock()
|
||||||
|
|
||||||
_, inode, err := fs.walkExistingLocked(ctx, rp)
|
_, inode, err := fs.walkExistingLocked(ctx, rp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -111,17 +111,18 @@ func (d *auxvData) Generate(ctx context.Context, buf *bytes.Buffer) error {
|
||||||
}
|
}
|
||||||
defer m.DecUsers(ctx)
|
defer m.DecUsers(ctx)
|
||||||
|
|
||||||
// Space for buffer with AT_NULL (0) terminator at the end.
|
|
||||||
auxv := m.Auxv()
|
auxv := m.Auxv()
|
||||||
|
// Space for buffer with AT_NULL (0) terminator at the end.
|
||||||
buf.Grow((len(auxv) + 1) * 16)
|
buf.Grow((len(auxv) + 1) * 16)
|
||||||
for _, e := range auxv {
|
for _, e := range auxv {
|
||||||
var tmp [8]byte
|
var tmp [16]byte
|
||||||
usermem.ByteOrder.PutUint64(tmp[:], e.Key)
|
usermem.ByteOrder.PutUint64(tmp[:8], e.Key)
|
||||||
buf.Write(tmp[:])
|
usermem.ByteOrder.PutUint64(tmp[8:], uint64(e.Value))
|
||||||
|
|
||||||
usermem.ByteOrder.PutUint64(tmp[:], uint64(e.Value))
|
|
||||||
buf.Write(tmp[:])
|
buf.Write(tmp[:])
|
||||||
}
|
}
|
||||||
|
var atNull [16]byte
|
||||||
|
buf.Write(atNull[:])
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ func newSysDir(root *auth.Credentials, inoGen InoGenerator, k *kernel.Kernel) *k
|
||||||
"shmmni": newDentry(root, inoGen.NextIno(), 0444, shmData(linux.SHMMNI)),
|
"shmmni": newDentry(root, inoGen.NextIno(), 0444, shmData(linux.SHMMNI)),
|
||||||
}),
|
}),
|
||||||
"vm": kernfs.NewStaticDir(root, inoGen.NextIno(), 0555, map[string]*kernfs.Dentry{
|
"vm": kernfs.NewStaticDir(root, inoGen.NextIno(), 0555, map[string]*kernfs.Dentry{
|
||||||
"mmap_min_addr": newDentry(root, inoGen.NextIno(), 0444, &mmapMinAddrData{}),
|
"mmap_min_addr": newDentry(root, inoGen.NextIno(), 0444, &mmapMinAddrData{k: k}),
|
||||||
"overcommit_memory": newDentry(root, inoGen.NextIno(), 0444, newStaticFile("0\n")),
|
"overcommit_memory": newDentry(root, inoGen.NextIno(), 0444, newStaticFile("0\n")),
|
||||||
}),
|
}),
|
||||||
"net": newSysNetDir(root, inoGen, k),
|
"net": newSysNetDir(root, inoGen, k),
|
||||||
|
|
|
@ -148,7 +148,7 @@ func (mm *MemoryManager) appendVMAMapsEntryLocked(ctx context.Context, vseg vmaI
|
||||||
|
|
||||||
// Do not include the guard page: fs/proc/task_mmu.c:show_map_vma() =>
|
// Do not include the guard page: fs/proc/task_mmu.c:show_map_vma() =>
|
||||||
// stack_guard_page_start().
|
// stack_guard_page_start().
|
||||||
fmt.Fprintf(b, "%08x-%08x %s%s %08x %02x:%02x %d ",
|
lineLen, _ := fmt.Fprintf(b, "%08x-%08x %s%s %08x %02x:%02x %d ",
|
||||||
vseg.Start(), vseg.End(), vma.realPerms, private, vma.off, devMajor, devMinor, ino)
|
vseg.Start(), vseg.End(), vma.realPerms, private, vma.off, devMajor, devMinor, ino)
|
||||||
|
|
||||||
// Figure out our filename or hint.
|
// Figure out our filename or hint.
|
||||||
|
@ -165,7 +165,7 @@ func (mm *MemoryManager) appendVMAMapsEntryLocked(ctx context.Context, vseg vmaI
|
||||||
}
|
}
|
||||||
if s != "" {
|
if s != "" {
|
||||||
// Per linux, we pad until the 74th character.
|
// Per linux, we pad until the 74th character.
|
||||||
if pad := 73 - b.Len(); pad > 0 {
|
if pad := 73 - lineLen; pad > 0 {
|
||||||
b.WriteString(strings.Repeat(" ", pad))
|
b.WriteString(strings.Repeat(" ", pad))
|
||||||
}
|
}
|
||||||
b.WriteString(s)
|
b.WriteString(s)
|
||||||
|
|
|
@ -130,7 +130,7 @@ func (cb *getdentsCallback) Handle(dirent vfs.Dirent) error {
|
||||||
if cb.t.Arch().Width() != 8 {
|
if cb.t.Arch().Width() != 8 {
|
||||||
panic(fmt.Sprintf("unsupported sizeof(unsigned long): %d", cb.t.Arch().Width()))
|
panic(fmt.Sprintf("unsupported sizeof(unsigned long): %d", cb.t.Arch().Width()))
|
||||||
}
|
}
|
||||||
size := 8 + 8 + 2 + 1 + 1 + 1 + len(dirent.Name)
|
size := 8 + 8 + 2 + 1 + 1 + len(dirent.Name)
|
||||||
size = (size + 7) &^ 7 // round up to multiple of sizeof(long)
|
size = (size + 7) &^ 7 // round up to multiple of sizeof(long)
|
||||||
if size > cb.remaining {
|
if size > cb.remaining {
|
||||||
return syserror.EINVAL
|
return syserror.EINVAL
|
||||||
|
@ -143,11 +143,11 @@ func (cb *getdentsCallback) Handle(dirent vfs.Dirent) error {
|
||||||
// Zero out all remaining bytes in buf, including the NUL terminator
|
// Zero out all remaining bytes in buf, including the NUL terminator
|
||||||
// after dirent.Name and the zero padding byte between the name and
|
// after dirent.Name and the zero padding byte between the name and
|
||||||
// dirent type.
|
// dirent type.
|
||||||
bufTail := buf[18+len(dirent.Name):]
|
bufTail := buf[18+len(dirent.Name) : size-1]
|
||||||
for i := range bufTail {
|
for i := range bufTail {
|
||||||
bufTail[i] = 0
|
bufTail[i] = 0
|
||||||
}
|
}
|
||||||
bufTail[2] = dirent.Type
|
buf[size-1] = dirent.Type
|
||||||
}
|
}
|
||||||
n, err := cb.t.CopyOutBytes(cb.addr, buf)
|
n, err := cb.t.CopyOutBytes(cb.addr, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -111,10 +111,10 @@ type FileDescriptionOptions struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init must be called before first use of fd. If it succeeds, it takes
|
// Init must be called before first use of fd. If it succeeds, it takes
|
||||||
// references on mnt and d. statusFlags is the initial file description status
|
// references on mnt and d. flags is the initial file description flags, which
|
||||||
// flags, which is usually the full set of flags passed to open(2).
|
// is usually the full set of flags passed to open(2).
|
||||||
func (fd *FileDescription) Init(impl FileDescriptionImpl, statusFlags uint32, mnt *Mount, d *Dentry, opts *FileDescriptionOptions) error {
|
func (fd *FileDescription) Init(impl FileDescriptionImpl, flags uint32, mnt *Mount, d *Dentry, opts *FileDescriptionOptions) error {
|
||||||
writable := MayWriteFileWithOpenFlags(statusFlags)
|
writable := MayWriteFileWithOpenFlags(flags)
|
||||||
if writable {
|
if writable {
|
||||||
if err := mnt.CheckBeginWrite(); err != nil {
|
if err := mnt.CheckBeginWrite(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -122,7 +122,10 @@ func (fd *FileDescription) Init(impl FileDescriptionImpl, statusFlags uint32, mn
|
||||||
}
|
}
|
||||||
|
|
||||||
fd.refs = 1
|
fd.refs = 1
|
||||||
fd.statusFlags = statusFlags
|
|
||||||
|
// Remove "file creation flags" to mirror the behavior from file.f_flags in
|
||||||
|
// fs/open.c:do_dentry_open
|
||||||
|
fd.statusFlags = flags &^ (linux.O_CREAT | linux.O_EXCL | linux.O_NOCTTY | linux.O_TRUNC)
|
||||||
fd.vd = VirtualDentry{
|
fd.vd = VirtualDentry{
|
||||||
mount: mnt,
|
mount: mnt,
|
||||||
dentry: d,
|
dentry: d,
|
||||||
|
@ -130,7 +133,7 @@ func (fd *FileDescription) Init(impl FileDescriptionImpl, statusFlags uint32, mn
|
||||||
mnt.IncRef()
|
mnt.IncRef()
|
||||||
d.IncRef()
|
d.IncRef()
|
||||||
fd.opts = *opts
|
fd.opts = *opts
|
||||||
fd.readable = MayReadFileWithOpenFlags(statusFlags)
|
fd.readable = MayReadFileWithOpenFlags(flags)
|
||||||
fd.writable = writable
|
fd.writable = writable
|
||||||
fd.impl = impl
|
fd.impl = impl
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue