diff options
Diffstat (limited to 'pkg/sentry/fsimpl/fuse')
-rw-r--r-- | pkg/sentry/fsimpl/fuse/fuse_state_autogen.go | 53 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/fuse/fusefs.go | 63 |
2 files changed, 53 insertions, 63 deletions
diff --git a/pkg/sentry/fsimpl/fuse/fuse_state_autogen.go b/pkg/sentry/fsimpl/fuse/fuse_state_autogen.go index 3c189317f..4c8bc4410 100644 --- a/pkg/sentry/fsimpl/fuse/fuse_state_autogen.go +++ b/pkg/sentry/fsimpl/fuse/fuse_state_autogen.go @@ -271,12 +271,11 @@ func (i *inode) StateTypeName() string { func (i *inode) StateFields() []string { return []string{ "inodeRefs", + "InodeAlwaysValid", "InodeAttrs", "InodeDirectoryNoNewChildren", - "InodeNoDynamicLookup", "InodeNotSymlink", "OrderedChildren", - "dentry", "fs", "metadataMu", "nodeID", @@ -294,42 +293,40 @@ func (i *inode) beforeSave() {} func (i *inode) StateSave(stateSinkObject state.Sink) { i.beforeSave() stateSinkObject.Save(0, &i.inodeRefs) - stateSinkObject.Save(1, &i.InodeAttrs) - stateSinkObject.Save(2, &i.InodeDirectoryNoNewChildren) - stateSinkObject.Save(3, &i.InodeNoDynamicLookup) + stateSinkObject.Save(1, &i.InodeAlwaysValid) + stateSinkObject.Save(2, &i.InodeAttrs) + stateSinkObject.Save(3, &i.InodeDirectoryNoNewChildren) stateSinkObject.Save(4, &i.InodeNotSymlink) stateSinkObject.Save(5, &i.OrderedChildren) - stateSinkObject.Save(6, &i.dentry) - stateSinkObject.Save(7, &i.fs) - stateSinkObject.Save(8, &i.metadataMu) - stateSinkObject.Save(9, &i.nodeID) - stateSinkObject.Save(10, &i.locks) - stateSinkObject.Save(11, &i.size) - stateSinkObject.Save(12, &i.attributeVersion) - stateSinkObject.Save(13, &i.attributeTime) - stateSinkObject.Save(14, &i.version) - stateSinkObject.Save(15, &i.link) + stateSinkObject.Save(6, &i.fs) + stateSinkObject.Save(7, &i.metadataMu) + stateSinkObject.Save(8, &i.nodeID) + stateSinkObject.Save(9, &i.locks) + stateSinkObject.Save(10, &i.size) + stateSinkObject.Save(11, &i.attributeVersion) + stateSinkObject.Save(12, &i.attributeTime) + stateSinkObject.Save(13, &i.version) + stateSinkObject.Save(14, &i.link) } func (i *inode) afterLoad() {} func (i *inode) StateLoad(stateSourceObject state.Source) { stateSourceObject.Load(0, &i.inodeRefs) - stateSourceObject.Load(1, &i.InodeAttrs) - stateSourceObject.Load(2, &i.InodeDirectoryNoNewChildren) - stateSourceObject.Load(3, &i.InodeNoDynamicLookup) + stateSourceObject.Load(1, &i.InodeAlwaysValid) + stateSourceObject.Load(2, &i.InodeAttrs) + stateSourceObject.Load(3, &i.InodeDirectoryNoNewChildren) stateSourceObject.Load(4, &i.InodeNotSymlink) stateSourceObject.Load(5, &i.OrderedChildren) - stateSourceObject.Load(6, &i.dentry) - stateSourceObject.Load(7, &i.fs) - stateSourceObject.Load(8, &i.metadataMu) - stateSourceObject.Load(9, &i.nodeID) - stateSourceObject.Load(10, &i.locks) - stateSourceObject.Load(11, &i.size) - stateSourceObject.Load(12, &i.attributeVersion) - stateSourceObject.Load(13, &i.attributeTime) - stateSourceObject.Load(14, &i.version) - stateSourceObject.Load(15, &i.link) + stateSourceObject.Load(6, &i.fs) + stateSourceObject.Load(7, &i.metadataMu) + stateSourceObject.Load(8, &i.nodeID) + stateSourceObject.Load(9, &i.locks) + stateSourceObject.Load(10, &i.size) + stateSourceObject.Load(11, &i.attributeVersion) + stateSourceObject.Load(12, &i.attributeTime) + stateSourceObject.Load(13, &i.version) + stateSourceObject.Load(14, &i.link) } func (r *inodeRefs) StateTypeName() string { diff --git a/pkg/sentry/fsimpl/fuse/fusefs.go b/pkg/sentry/fsimpl/fuse/fusefs.go index 65786e42a..1a388f54f 100644 --- a/pkg/sentry/fsimpl/fuse/fusefs.go +++ b/pkg/sentry/fsimpl/fuse/fusefs.go @@ -249,14 +249,12 @@ func (fs *filesystem) Release(ctx context.Context) { // +stateify savable type inode struct { inodeRefs + kernfs.InodeAlwaysValid kernfs.InodeAttrs kernfs.InodeDirectoryNoNewChildren - kernfs.InodeNoDynamicLookup kernfs.InodeNotSymlink kernfs.OrderedChildren - dentry kernfs.Dentry - // the owning filesystem. fs is immutable. fs *filesystem @@ -284,26 +282,24 @@ type inode struct { } func (fs *filesystem) newRootInode(creds *auth.Credentials, mode linux.FileMode) *kernfs.Dentry { - i := &inode{fs: fs} + i := &inode{fs: fs, nodeID: 1} i.InodeAttrs.Init(creds, linux.UNNAMED_MAJOR, fs.devMinor, 1, linux.ModeDirectory|0755) i.OrderedChildren.Init(kernfs.OrderedChildrenOptions{}) i.EnableLeakCheck() - i.dentry.Init(i) - i.nodeID = 1 - return &i.dentry + var d kernfs.Dentry + d.Init(&fs.Filesystem, i) + return &d } -func (fs *filesystem) newInode(nodeID uint64, attr linux.FUSEAttr) *kernfs.Dentry { +func (fs *filesystem) newInode(nodeID uint64, attr linux.FUSEAttr) kernfs.Inode { i := &inode{fs: fs, nodeID: nodeID} creds := auth.Credentials{EffectiveKGID: auth.KGID(attr.UID), EffectiveKUID: auth.KUID(attr.UID)} i.InodeAttrs.Init(&creds, linux.UNNAMED_MAJOR, fs.devMinor, fs.NextIno(), linux.FileMode(attr.Mode)) atomic.StoreUint64(&i.size, attr.Size) i.OrderedChildren.Init(kernfs.OrderedChildrenOptions{}) i.EnableLeakCheck() - i.dentry.Init(i) - - return &i.dentry + return i } // Open implements kernfs.Inode.Open. @@ -410,23 +406,27 @@ func (i *inode) Open(ctx context.Context, rp *vfs.ResolvingPath, d *kernfs.Dentr } // Lookup implements kernfs.Inode.Lookup. -func (i *inode) Lookup(ctx context.Context, name string) (*kernfs.Dentry, error) { +func (i *inode) Lookup(ctx context.Context, name string) (kernfs.Inode, error) { in := linux.FUSELookupIn{Name: name} return i.newEntry(ctx, name, 0, linux.FUSE_LOOKUP, &in) } +// Keep implements kernfs.Inode.Keep. +func (i *inode) Keep() bool { + // Return true so that kernfs keeps the new dentry pointing to this + // inode in the dentry tree. This is needed because inodes created via + // Lookup are not temporary. They might refer to existing files on server + // that can be Unlink'd/Rmdir'd. + return true +} + // IterDirents implements kernfs.Inode.IterDirents. func (*inode) IterDirents(ctx context.Context, callback vfs.IterDirentsCallback, offset, relOffset int64) (int64, error) { return offset, nil } -// Valid implements kernfs.Inode.Valid. -func (*inode) Valid(ctx context.Context) bool { - return true -} - // NewFile implements kernfs.Inode.NewFile. -func (i *inode) NewFile(ctx context.Context, name string, opts vfs.OpenOptions) (*kernfs.Dentry, error) { +func (i *inode) NewFile(ctx context.Context, name string, opts vfs.OpenOptions) (kernfs.Inode, error) { kernelTask := kernel.TaskFromContext(ctx) if kernelTask == nil { log.Warningf("fusefs.Inode.NewFile: couldn't get kernel task from context", i.nodeID) @@ -444,7 +444,7 @@ func (i *inode) NewFile(ctx context.Context, name string, opts vfs.OpenOptions) } // NewNode implements kernfs.Inode.NewNode. -func (i *inode) NewNode(ctx context.Context, name string, opts vfs.MknodOptions) (*kernfs.Dentry, error) { +func (i *inode) NewNode(ctx context.Context, name string, opts vfs.MknodOptions) (kernfs.Inode, error) { in := linux.FUSEMknodIn{ MknodMeta: linux.FUSEMknodMeta{ Mode: uint32(opts.Mode), @@ -457,7 +457,7 @@ func (i *inode) NewNode(ctx context.Context, name string, opts vfs.MknodOptions) } // NewSymlink implements kernfs.Inode.NewSymlink. -func (i *inode) NewSymlink(ctx context.Context, name, target string) (*kernfs.Dentry, error) { +func (i *inode) NewSymlink(ctx context.Context, name, target string) (kernfs.Inode, error) { in := linux.FUSESymLinkIn{ Name: name, Target: target, @@ -466,7 +466,7 @@ func (i *inode) NewSymlink(ctx context.Context, name, target string) (*kernfs.De } // Unlink implements kernfs.Inode.Unlink. -func (i *inode) Unlink(ctx context.Context, name string, child *kernfs.Dentry) error { +func (i *inode) Unlink(ctx context.Context, name string, child kernfs.Inode) error { kernelTask := kernel.TaskFromContext(ctx) if kernelTask == nil { log.Warningf("fusefs.Inode.newEntry: couldn't get kernel task from context", i.nodeID) @@ -482,14 +482,11 @@ func (i *inode) Unlink(ctx context.Context, name string, child *kernfs.Dentry) e return err } // only return error, discard res. - if err := res.Error(); err != nil { - return err - } - return i.dentry.RemoveChildLocked(name, child) + return res.Error() } // NewDir implements kernfs.Inode.NewDir. -func (i *inode) NewDir(ctx context.Context, name string, opts vfs.MkdirOptions) (*kernfs.Dentry, error) { +func (i *inode) NewDir(ctx context.Context, name string, opts vfs.MkdirOptions) (kernfs.Inode, error) { in := linux.FUSEMkdirIn{ MkdirMeta: linux.FUSEMkdirMeta{ Mode: uint32(opts.Mode), @@ -501,7 +498,7 @@ func (i *inode) NewDir(ctx context.Context, name string, opts vfs.MkdirOptions) } // RmDir implements kernfs.Inode.RmDir. -func (i *inode) RmDir(ctx context.Context, name string, child *kernfs.Dentry) error { +func (i *inode) RmDir(ctx context.Context, name string, child kernfs.Inode) error { fusefs := i.fs task, creds := kernel.TaskFromContext(ctx), auth.CredentialsFromContext(ctx) @@ -515,16 +512,12 @@ func (i *inode) RmDir(ctx context.Context, name string, child *kernfs.Dentry) er if err != nil { return err } - if err := res.Error(); err != nil { - return err - } - - return i.dentry.RemoveChildLocked(name, child) + return res.Error() } // newEntry calls FUSE server for entry creation and allocates corresponding entry according to response. // Shared by FUSE_MKNOD, FUSE_MKDIR, FUSE_SYMLINK, FUSE_LINK and FUSE_LOOKUP. -func (i *inode) newEntry(ctx context.Context, name string, fileType linux.FileMode, opcode linux.FUSEOpcode, payload marshal.Marshallable) (*kernfs.Dentry, error) { +func (i *inode) newEntry(ctx context.Context, name string, fileType linux.FileMode, opcode linux.FUSEOpcode, payload marshal.Marshallable) (kernfs.Inode, error) { kernelTask := kernel.TaskFromContext(ctx) if kernelTask == nil { log.Warningf("fusefs.Inode.newEntry: couldn't get kernel task from context", i.nodeID) @@ -734,8 +727,8 @@ func (i *inode) Stat(ctx context.Context, fs *vfs.Filesystem, opts vfs.StatOptio } // DecRef implements kernfs.Inode.DecRef. -func (i *inode) DecRef(context.Context) { - i.inodeRefs.DecRef(i.Destroy) +func (i *inode) DecRef(ctx context.Context) { + i.inodeRefs.DecRef(func() { i.Destroy(ctx) }) } // StatFS implements kernfs.Inode.StatFS. |