diff options
author | Nicolas Lacasse <nlacasse@google.com> | 2019-08-01 14:23:54 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2019-08-01 14:25:14 -0700 |
commit | f2b25aeac7b5ba44144d003fbb2ae657461b8e9b (patch) | |
tree | 3534f3a97327899a0f0c80d3863c835e3d54fccc | |
parent | 79511e8a50facd509b8180d0160762b510dd6196 (diff) |
tmpfs and ramfs Dirs should drop references on children in Release().
This is the source of many warnings like:
AtomicRefCount 0x7f5ff84e3500 owned by "fs.Inode" garbage collected with ref count of 1 (want 0)
PiperOrigin-RevId: 261197093
-rw-r--r-- | pkg/sentry/fs/ramfs/dir.go | 23 | ||||
-rw-r--r-- | pkg/sentry/fs/tmpfs/tmpfs.go | 6 |
2 files changed, 23 insertions, 6 deletions
diff --git a/pkg/sentry/fs/ramfs/dir.go b/pkg/sentry/fs/ramfs/dir.go index f3e984c24..78e082b8e 100644 --- a/pkg/sentry/fs/ramfs/dir.go +++ b/pkg/sentry/fs/ramfs/dir.go @@ -53,7 +53,6 @@ type Dir struct { fsutil.InodeGenericChecker `state:"nosave"` fsutil.InodeIsDirAllocate `state:"nosave"` fsutil.InodeIsDirTruncate `state:"nosave"` - fsutil.InodeNoopRelease `state:"nosave"` fsutil.InodeNoopWriteOut `state:"nosave"` fsutil.InodeNotMappable `state:"nosave"` fsutil.InodeNotSocket `state:"nosave"` @@ -84,7 +83,8 @@ type Dir struct { var _ fs.InodeOperations = (*Dir)(nil) -// NewDir returns a new Dir with the given contents and attributes. +// NewDir returns a new Dir with the given contents and attributes. A reference +// on each fs.Inode in the `contents` map will be donated to this Dir. func NewDir(ctx context.Context, contents map[string]*fs.Inode, owner fs.FileOwner, perms fs.FilePermissions) *Dir { d := &Dir{ InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, owner, perms, linux.RAMFS_MAGIC), @@ -138,7 +138,7 @@ func (d *Dir) addChildLocked(ctx context.Context, name string, inode *fs.Inode) d.NotifyModificationAndStatusChange(ctx) } -// AddChild adds a child to this dir. +// AddChild adds a child to this dir, inheriting its reference. func (d *Dir) AddChild(ctx context.Context, name string, inode *fs.Inode) { d.mu.Lock() defer d.mu.Unlock() @@ -172,7 +172,9 @@ func (d *Dir) Children() ([]string, map[string]fs.DentAttr) { return namesCopy, entriesCopy } -// removeChildLocked attempts to remove an entry from this directory. +// removeChildLocked attempts to remove an entry from this directory. It +// returns the removed fs.Inode along with its reference, which callers are +// responsible for decrementing. func (d *Dir) removeChildLocked(ctx context.Context, name string) (*fs.Inode, error) { inode, ok := d.children[name] if !ok { @@ -253,7 +255,8 @@ func (d *Dir) RemoveDirectory(ctx context.Context, _ *fs.Inode, name string) err return nil } -// Lookup loads an inode at p into a Dirent. +// Lookup loads an inode at p into a Dirent. It returns the fs.Dirent along +// with a reference. func (d *Dir) Lookup(ctx context.Context, _ *fs.Inode, p string) (*fs.Dirent, error) { if len(p) > linux.NAME_MAX { return nil, syserror.ENAMETOOLONG @@ -408,6 +411,16 @@ func (*Dir) Rename(ctx context.Context, inode *fs.Inode, oldParent *fs.Inode, ol return Rename(ctx, oldParent.InodeOperations, oldName, newParent.InodeOperations, newName, replacement) } +// Release implements fs.InodeOperation.Release. +func (d *Dir) Release(_ context.Context) { + // Drop references on all children. + d.mu.Lock() + for _, i := range d.children { + i.DecRef() + } + d.mu.Unlock() +} + // dirFileOperations implements fs.FileOperations for a ramfs directory. // // +stateify savable diff --git a/pkg/sentry/fs/tmpfs/tmpfs.go b/pkg/sentry/fs/tmpfs/tmpfs.go index 0f4497cd6..159fb7c08 100644 --- a/pkg/sentry/fs/tmpfs/tmpfs.go +++ b/pkg/sentry/fs/tmpfs/tmpfs.go @@ -56,7 +56,6 @@ func rename(ctx context.Context, oldParent *fs.Inode, oldName string, newParent type Dir struct { fsutil.InodeGenericChecker `state:"nosave"` fsutil.InodeIsDirTruncate `state:"nosave"` - fsutil.InodeNoopRelease `state:"nosave"` fsutil.InodeNoopWriteOut `state:"nosave"` fsutil.InodeNotMappable `state:"nosave"` fsutil.InodeNotSocket `state:"nosave"` @@ -252,6 +251,11 @@ func (d *Dir) Allocate(ctx context.Context, node *fs.Inode, offset, length int64 return d.ramfsDir.Allocate(ctx, node, offset, length) } +// Release implements fs.InodeOperations.Release. +func (d *Dir) Release(ctx context.Context) { + d.ramfsDir.Release(ctx) +} + // Symlink is a symlink. // // +stateify savable |