summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fsimpl/fuse
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/fsimpl/fuse')
-rw-r--r--pkg/sentry/fsimpl/fuse/fuse_state_autogen.go53
-rw-r--r--pkg/sentry/fsimpl/fuse/fusefs.go63
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.