Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Internal change. #11247

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pkg/sentry/fsimpl/cgroupfs/cgroupfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ type dir struct {
kernfs.InodeNotSymlink
kernfs.InodeWatches
kernfs.OrderedChildren
kernfs.InodeFSOwned
implStatFS

locks vfs.FileLocks
Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/fsimpl/devpts/devpts.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ type rootInode struct {
kernfs.InodeTemporary // This holds no meaning as this inode can't be Looked up and is always valid.
kernfs.InodeWatches
kernfs.OrderedChildren
kernfs.InodeFSOwned
rootInodeRefs

locks vfs.FileLocks
Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/fsimpl/devpts/master.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type masterInode struct {
kernfs.InodeNotAnonymous
kernfs.InodeNotDirectory
kernfs.InodeNotSymlink
kernfs.InodeFSOwned
kernfs.InodeWatches

locks vfs.FileLocks
Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/fsimpl/devpts/replica.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type replicaInode struct {
kernfs.InodeNotDirectory
kernfs.InodeNotSymlink
kernfs.InodeWatches
kernfs.InodeFSOwned

locks vfs.FileLocks

Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/fsimpl/fuse/inode.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type inode struct {
kernfs.InodeWatches
kernfs.OrderedChildren
kernfs.CachedMappable
kernfs.InodeFSOwned

// the owning filesystem. fs is immutable.
fs *filesystem
Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/fsimpl/host/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ type inode struct {
kernfs.InodeNotSymlink
kernfs.InodeTemporary // This holds no meaning as this inode can't be Looked up and is always valid.
kernfs.InodeWatches
kernfs.InodeFSOwned

locks vfs.FileLocks

Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/fsimpl/kernfs/dynamic_bytes_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type DynamicBytesFile struct {
InodeNotDirectory
InodeNotSymlink
InodeWatches
InodeFSOwned

locks vfs.FileLocks
// data can additionally implement vfs.WritableDynamicBytesSource to support
Expand Down
12 changes: 12 additions & 0 deletions pkg/sentry/fsimpl/kernfs/filesystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ func (fs *Filesystem) revalidateChildLocked(ctx context.Context, vfsObj *vfs.Vir
parent.dirMu.Lock()
// Check for concurrent insertion of a new cached dentry.
child = parent.children[name]

}
if child == nil {
// Dentry isn't cached; it either doesn't exist or failed revalidation.
Expand Down Expand Up @@ -155,6 +156,11 @@ func (fs *Filesystem) invalidateRemovedChildLocked(ctx context.Context, vfsObj *
d := toInvalidate[len(toInvalidate)-1]
toInvalidate = toInvalidate[:len(toInvalidate)-1]

if d.cached {
d.fs.cachedDentries.Remove(d)
d.fs.cachedDentriesLen--
d.cached = false
}
if d.inode.Keep() {
fs.deferDecRef(d)
}
Expand All @@ -171,6 +177,12 @@ func (fs *Filesystem) invalidateRemovedChildLocked(ctx context.Context, vfsObj *
}
d.dirMu.Unlock()
}
if d.refs.Load() == 0 {
d.destroy(ctx)
if parent := d.parent.Load(); parent != nil {
parent.decRefLocked(ctx)
}
}
}
}

Expand Down
13 changes: 13 additions & 0 deletions pkg/sentry/fsimpl/kernfs/inode_impl_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,7 @@ type StaticDirectory struct {
InodeWatches
OrderedChildren
StaticDirectoryRefs
InodeFSOwned

locks vfs.FileLocks
fdOpts GenericDirectoryFDOptions
Expand Down Expand Up @@ -845,3 +846,15 @@ type InodeNotAnonymous struct{}
func (*InodeNotAnonymous) Anonymous() bool {
return false
}

// InodeFSOwned represents inodes whose lifecycle is entirely managed by the
// filesystem.
//
// +stateify savable
type InodeFSOwned struct{}

// AddInvalidateCallback implements Inode.AddInvalidateCallback.
func (*InodeFSOwned) AddInvalidateCallback(d *Dentry) {}

// RemoveInvalidateCallback implements Remove.AddInvalidateCallback.
func (*InodeFSOwned) RemoveInvalidateCallback(d *Dentry) {}
39 changes: 39 additions & 0 deletions pkg/sentry/fsimpl/kernfs/kernfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,34 @@ func (d *Dentry) decRefLocked(ctx context.Context) {
}
}

// Invalidate invalidates the dentry and its children.
func (d *Dentry) Invalidate(ctx context.Context) {
d.fs.mu.Lock()
defer d.fs.processDeferredDecRefs(ctx)
defer d.fs.mu.Unlock()
if d.vfsd.IsDead() {
return
}
parent := d.parent.Load()
if parent == nil {
return
}
parent.dirMu.Lock()
if parent.vfsd.IsDead() {
parent.dirMu.Unlock()
return
}
child := parent.children[d.name]
if child != d {
parent.dirMu.Unlock()
return
}
delete(parent.children, d.name)
parent.dirMu.Unlock()

d.fs.invalidateRemovedChildLocked(ctx, d.fs.vfsfs.VirtualFilesystem(), child)
}

// cacheLocked should be called after d's reference count becomes 0. The ref
// count check may happen before acquiring d.fs.mu so there might be a race
// condition where the ref count is increased again by the time the caller
Expand Down Expand Up @@ -451,6 +479,7 @@ func (d *Dentry) destroy(ctx context.Context) {
panic("dentry.destroy() called with references on the dentry")
}

d.inode.RemoveInvalidateCallback(d)
d.inode.DecRef(ctx) // IncRef from Init.

refs.Unregister(d)
Expand Down Expand Up @@ -505,6 +534,7 @@ func (d *Dentry) Init(fs *Filesystem, inode Inode) {
d.flags = atomicbitops.FromUint32(d.flags.RacyLoad() | dflagsIsSymlink)
}
refs.Register(d)
inode.AddInvalidateCallback(d)
}

// VFSDentry returns the generic vfs dentry for this kernfs dentry.
Expand Down Expand Up @@ -732,6 +762,15 @@ type Inode interface {
// Anonymous indicates that the Inode is anonymous. It will never have
// a name or parent.
Anonymous() bool

// AddInvalidateCallback registers invalidate callbacks associated with
// the new dentry. This is used for inodes representing objects with
// independent lifetimes.
AddInvalidateCallback(d *Dentry)

// RemoveInvalidateCallback unregisters the callbacks previously
// registered with AddInvalidateCallback.
RemoveInvalidateCallback(d *Dentry)
}

type inodeRefs interface {
Expand Down
2 changes: 2 additions & 0 deletions pkg/sentry/fsimpl/kernfs/kernfs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ type readonlyDir struct {
kernfs.InodeTemporary
kernfs.InodeWatches
kernfs.OrderedChildren
kernfs.InodeFSOwned

locks vfs.FileLocks
}
Expand Down Expand Up @@ -146,6 +147,7 @@ type dir struct {
kernfs.InodeTemporary
kernfs.InodeWatches
kernfs.OrderedChildren
kernfs.InodeFSOwned

locks vfs.FileLocks

Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/fsimpl/kernfs/save_restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
func (d *Dentry) afterLoad(context.Context) {
if d.refs.Load() >= 0 {
refs.Register(d)
d.inode.AddInvalidateCallback(d)
}
}

Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/fsimpl/kernfs/symlink.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type StaticSymlink struct {
InodeSymlink
InodeNoStatFS
InodeWatches
InodeFSOwned

target string
}
Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/fsimpl/kernfs/synthetic_directory.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type syntheticDirectory struct {
InodeWatches
OrderedChildren
syntheticDirectoryRefs
InodeFSOwned

locks vfs.FileLocks
}
Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/fsimpl/mqfs/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type rootInode struct {
kernfs.InodeTemporary
kernfs.InodeWatches
kernfs.OrderedChildren
kernfs.InodeFSOwned

locks vfs.FileLocks
}
Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/fsimpl/nsfs/nsfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ type Inode struct {
kernfs.InodeNotDirectory
kernfs.InodeNotSymlink
kernfs.InodeWatches
kernfs.InodeFSOwned
inodeRefs

locks vfs.FileLocks
Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/fsimpl/pipefs/pipefs.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ type inode struct {
kernfs.InodeNotSymlink
kernfs.InodeNoopRefCount
kernfs.InodeWatches
kernfs.InodeFSOwned

locks vfs.FileLocks
pipe *pipe.VFSPipe
Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/fsimpl/proc/subtasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type subtasksInode struct {
kernfs.InodeTemporary
kernfs.InodeWatches
kernfs.OrderedChildren
kernfs.InodeFSOwned
subtasksInodeRefs

locks vfs.FileLocks
Expand Down
12 changes: 12 additions & 0 deletions pkg/sentry/fsimpl/proc/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,18 @@ func (fs *filesystem) newTaskInode(ctx context.Context, task *kernel.Task, pidns
return inode, nil
}

// AddInvalidateCallback implements kernfs.Inode.AddInvalidateCallback.
func (i *taskInode) AddInvalidateCallback(d *kernfs.Dentry) {
if !i.task.RegisterOnDestroyAction(d, d.Invalidate) {
go func() { d.Invalidate(context.Background()) }()
}
}

// RemoveInvalidateCallback implements kernfs.Inode.AddInvalidateCallback.
func (i *taskInode) RemoveInvalidateCallback(d *kernfs.Dentry) {
i.task.UnregisterOnDestroyAction(d)
}

// Valid implements kernfs.Inode.Valid. This inode remains valid as long
// as the task is still running. When it's dead, another tasks with the same
// PID could replace it.
Expand Down
3 changes: 3 additions & 0 deletions pkg/sentry/fsimpl/proc/task_fds.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ type fdDirInode struct {
kernfs.InodeTemporary
kernfs.InodeWatches
kernfs.OrderedChildren
kernfs.InodeFSOwned
}

var _ kernfs.Inode = (*fdDirInode)(nil)
Expand Down Expand Up @@ -202,6 +203,7 @@ type fdSymlink struct {
kernfs.InodeNotAnonymous
kernfs.InodeSymlink
kernfs.InodeWatches
kernfs.InodeFSOwned

fs *filesystem
task *kernel.Task
Expand Down Expand Up @@ -264,6 +266,7 @@ type fdInfoDirInode struct {
kernfs.InodeTemporary
kernfs.InodeWatches
kernfs.OrderedChildren
kernfs.InodeFSOwned
}

var _ kernfs.Inode = (*fdInfoDirInode)(nil)
Expand Down
6 changes: 6 additions & 0 deletions pkg/sentry/fsimpl/proc/task_files.go
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ type memInode struct {
kernfs.InodeNotDirectory
kernfs.InodeNotSymlink
kernfs.InodeWatches
kernfs.InodeFSOwned

task *kernel.Task
locks vfs.FileLocks
Expand Down Expand Up @@ -743,6 +744,7 @@ type statusInode struct {
kernfs.InodeNotDirectory
kernfs.InodeNotSymlink
kernfs.InodeWatches
kernfs.InodeFSOwned

task *kernel.Task
pidns *kernel.PIDNamespace
Expand Down Expand Up @@ -981,6 +983,7 @@ type exeSymlink struct {
kernfs.InodeNotAnonymous
kernfs.InodeSymlink
kernfs.InodeWatches
kernfs.InodeFSOwned

fs *filesystem
task *kernel.Task
Expand Down Expand Up @@ -1054,6 +1057,7 @@ type cwdSymlink struct {
kernfs.InodeNotAnonymous
kernfs.InodeSymlink
kernfs.InodeWatches
kernfs.InodeFSOwned

fs *filesystem
task *kernel.Task
Expand Down Expand Up @@ -1116,6 +1120,7 @@ type rootSymlink struct {
kernfs.InodeNotAnonymous
kernfs.InodeSymlink
kernfs.InodeWatches
kernfs.InodeFSOwned

fs *filesystem
task *kernel.Task
Expand Down Expand Up @@ -1360,6 +1365,7 @@ type namespaceInode struct {
kernfs.InodeNotDirectory
kernfs.InodeNotSymlink
kernfs.InodeWatches
kernfs.InodeFSOwned

locks vfs.FileLocks
}
Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/fsimpl/proc/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type tasksInode struct {
kernfs.InodeTemporary // This holds no meaning as this inode can't be Looked up and is always valid.
kernfs.InodeWatches
kernfs.OrderedChildren
kernfs.InodeFSOwned
tasksInodeRefs

locks vfs.FileLocks
Expand Down
2 changes: 2 additions & 0 deletions pkg/sentry/fsimpl/proc/tasks_files.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type selfSymlink struct {
kernfs.InodeNotAnonymous
kernfs.InodeSymlink
kernfs.InodeWatches
kernfs.InodeFSOwned

pidns *kernel.PIDNamespace
}
Expand Down Expand Up @@ -83,6 +84,7 @@ type threadSelfSymlink struct {
kernfs.InodeNotAnonymous
kernfs.InodeSymlink
kernfs.InodeWatches
kernfs.InodeFSOwned

pidns *kernel.PIDNamespace
}
Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/fsimpl/sockfs/sockfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ type inode struct {
kernfs.InodeNotDirectory
kernfs.InodeNotSymlink
kernfs.InodeWatches
kernfs.InodeFSOwned
}

// Open implements kernfs.Inode.Open.
Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/fsimpl/sys/kcov.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type kcovInode struct {
kernfs.InodeNotDirectory
kernfs.InodeNotSymlink
kernfs.InodeWatches
kernfs.InodeFSOwned
implStatFS
}

Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/fsimpl/sys/sys.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ type dir struct {
kernfs.InodeNotSymlink
kernfs.InodeTemporary
kernfs.InodeWatches
kernfs.InodeFSOwned
kernfs.OrderedChildren

locks vfs.FileLocks
Expand Down
Loading
Loading