diff --git a/conversions.go b/conversions.go index 3b83a13..b480dbd 100644 --- a/conversions.go +++ b/conversions.go @@ -50,13 +50,15 @@ func convertInMessage( } o = &fuseops.LookUpInodeOp{ - Parent: fuseops.InodeID(inMsg.Header().Nodeid), - Name: string(buf[:n-1]), + Parent: fuseops.InodeID(inMsg.Header().Nodeid), + Name: string(buf[:n-1]), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpGetattr: o = &fuseops.GetInodeAttributesOp{ - Inode: fuseops.InodeID(inMsg.Header().Nodeid), + Inode: fuseops.InodeID(inMsg.Header().Nodeid), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpSetattr: @@ -67,7 +69,8 @@ func convertInMessage( } to := &fuseops.SetInodeAttributesOp{ - Inode: fuseops.InodeID(inMsg.Header().Nodeid), + Inode: fuseops.InodeID(inMsg.Header().Nodeid), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } o = to @@ -104,8 +107,9 @@ func convertInMessage( } o = &fuseops.ForgetInodeOp{ - Inode: fuseops.InodeID(inMsg.Header().Nodeid), - N: in.Nlookup, + Inode: fuseops.InodeID(inMsg.Header().Nodeid), + N: in.Nlookup, + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpMkdir: @@ -131,7 +135,8 @@ func convertInMessage( // the fact that this is a directory is implicit in the fact that the // opcode is mkdir. But we want the correct mode to go through, so ensure // that os.ModeDir is set. - Mode: convertFileMode(in.Mode) | os.ModeDir, + Mode: convertFileMode(in.Mode) | os.ModeDir, + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpMknod: @@ -148,9 +153,10 @@ func convertInMessage( name = name[:i] o = &fuseops.MkNodeOp{ - Parent: fuseops.InodeID(inMsg.Header().Nodeid), - Name: string(name), - Mode: convertFileMode(in.Mode), + Parent: fuseops.InodeID(inMsg.Header().Nodeid), + Name: string(name), + Mode: convertFileMode(in.Mode), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpCreate: @@ -167,9 +173,10 @@ func convertInMessage( name = name[:i] o = &fuseops.CreateFileOp{ - Parent: fuseops.InodeID(inMsg.Header().Nodeid), - Name: string(name), - Mode: convertFileMode(in.Mode), + Parent: fuseops.InodeID(inMsg.Header().Nodeid), + Name: string(name), + Mode: convertFileMode(in.Mode), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpSymlink: @@ -185,9 +192,10 @@ func convertInMessage( newName, target := names[0:i], names[i+1:len(names)-1] o = &fuseops.CreateSymlinkOp{ - Parent: fuseops.InodeID(inMsg.Header().Nodeid), - Name: string(newName), - Target: string(target), + Parent: fuseops.InodeID(inMsg.Header().Nodeid), + Name: string(newName), + Target: string(target), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpRename: @@ -216,6 +224,7 @@ func convertInMessage( OldName: string(oldName), NewParent: fuseops.InodeID(in.Newdir), NewName: string(newName), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpUnlink: @@ -226,8 +235,9 @@ func convertInMessage( } o = &fuseops.UnlinkOp{ - Parent: fuseops.InodeID(inMsg.Header().Nodeid), - Name: string(buf[:n-1]), + Parent: fuseops.InodeID(inMsg.Header().Nodeid), + Name: string(buf[:n-1]), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpRmdir: @@ -238,18 +248,21 @@ func convertInMessage( } o = &fuseops.RmDirOp{ - Parent: fuseops.InodeID(inMsg.Header().Nodeid), - Name: string(buf[:n-1]), + Parent: fuseops.InodeID(inMsg.Header().Nodeid), + Name: string(buf[:n-1]), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpOpen: o = &fuseops.OpenFileOp{ - Inode: fuseops.InodeID(inMsg.Header().Nodeid), + Inode: fuseops.InodeID(inMsg.Header().Nodeid), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpOpendir: o = &fuseops.OpenDirOp{ - Inode: fuseops.InodeID(inMsg.Header().Nodeid), + Inode: fuseops.InodeID(inMsg.Header().Nodeid), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpRead: @@ -259,9 +272,10 @@ func convertInMessage( } to := &fuseops.ReadFileOp{ - Inode: fuseops.InodeID(inMsg.Header().Nodeid), - Handle: fuseops.HandleID(in.Fh), - Offset: int64(in.Offset), + Inode: fuseops.InodeID(inMsg.Header().Nodeid), + Handle: fuseops.HandleID(in.Fh), + Offset: int64(in.Offset), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } o = to @@ -283,9 +297,10 @@ func convertInMessage( } to := &fuseops.ReadDirOp{ - Inode: fuseops.InodeID(inMsg.Header().Nodeid), - Handle: fuseops.HandleID(in.Fh), - Offset: fuseops.DirOffset(in.Offset), + Inode: fuseops.InodeID(inMsg.Header().Nodeid), + Handle: fuseops.HandleID(in.Fh), + Offset: fuseops.DirOffset(in.Offset), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } o = to @@ -308,7 +323,8 @@ func convertInMessage( } o = &fuseops.ReleaseFileHandleOp{ - Handle: fuseops.HandleID(in.Fh), + Handle: fuseops.HandleID(in.Fh), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpReleasedir: @@ -319,7 +335,8 @@ func convertInMessage( } o = &fuseops.ReleaseDirHandleOp{ - Handle: fuseops.HandleID(in.Fh), + Handle: fuseops.HandleID(in.Fh), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpWrite: @@ -334,10 +351,11 @@ func convertInMessage( } o = &fuseops.WriteFileOp{ - Inode: fuseops.InodeID(inMsg.Header().Nodeid), - Handle: fuseops.HandleID(in.Fh), - Data: buf, - Offset: int64(in.Offset), + Inode: fuseops.InodeID(inMsg.Header().Nodeid), + Handle: fuseops.HandleID(in.Fh), + Data: buf, + Offset: int64(in.Offset), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpFsync: @@ -348,8 +366,9 @@ func convertInMessage( } o = &fuseops.SyncFileOp{ - Inode: fuseops.InodeID(inMsg.Header().Nodeid), - Handle: fuseops.HandleID(in.Fh), + Inode: fuseops.InodeID(inMsg.Header().Nodeid), + Handle: fuseops.HandleID(in.Fh), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpFlush: @@ -360,13 +379,15 @@ func convertInMessage( } o = &fuseops.FlushFileOp{ - Inode: fuseops.InodeID(inMsg.Header().Nodeid), - Handle: fuseops.HandleID(in.Fh), + Inode: fuseops.InodeID(inMsg.Header().Nodeid), + Handle: fuseops.HandleID(in.Fh), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpReadlink: o = &fuseops.ReadSymlinkOp{ - Inode: fuseops.InodeID(inMsg.Header().Nodeid), + Inode: fuseops.InodeID(inMsg.Header().Nodeid), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpStatfs: @@ -414,9 +435,10 @@ func convertInMessage( } o = &fuseops.CreateLinkOp{ - Parent: fuseops.InodeID(inMsg.Header().Nodeid), - Name: string(name), - Target: fuseops.InodeID(in.Oldnodeid), + Parent: fuseops.InodeID(inMsg.Header().Nodeid), + Name: string(name), + Target: fuseops.InodeID(in.Oldnodeid), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpRemovexattr: @@ -427,8 +449,9 @@ func convertInMessage( } o = &fuseops.RemoveXattrOp{ - Inode: fuseops.InodeID(inMsg.Header().Nodeid), - Name: string(buf[:n-1]), + Inode: fuseops.InodeID(inMsg.Header().Nodeid), + Name: string(buf[:n-1]), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpGetxattr: @@ -446,8 +469,9 @@ func convertInMessage( name = name[:i] to := &fuseops.GetXattrOp{ - Inode: fuseops.InodeID(inMsg.Header().Nodeid), - Name: string(name), + Inode: fuseops.InodeID(inMsg.Header().Nodeid), + Name: string(name), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } o = to @@ -470,7 +494,8 @@ func convertInMessage( } to := &fuseops.ListXattrOp{ - Inode: fuseops.InodeID(inMsg.Header().Nodeid), + Inode: fuseops.InodeID(inMsg.Header().Nodeid), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } o = to @@ -505,10 +530,11 @@ func convertInMessage( name, value := payload[:i], payload[i+1:len(payload)] o = &fuseops.SetXattrOp{ - Inode: fuseops.InodeID(inMsg.Header().Nodeid), - Name: string(name), - Value: value, - Flags: in.Flags, + Inode: fuseops.InodeID(inMsg.Header().Nodeid), + Name: string(name), + Value: value, + Flags: in.Flags, + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } case fusekernel.OpFallocate: type input fusekernel.FallocateIn @@ -518,11 +544,12 @@ func convertInMessage( } o = &fuseops.FallocateOp{ - Inode: fuseops.InodeID(inMsg.Header().Nodeid), - Handle: fuseops.HandleID(in.Fh), - Offset: in.Offset, - Length: in.Length, - Mode: in.Mode, + Inode: fuseops.InodeID(inMsg.Header().Nodeid), + Handle: fuseops.HandleID(in.Fh), + Offset: in.Offset, + Length: in.Length, + Mode: in.Mode, + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, } default: diff --git a/debug.go b/debug.go index 5ff86b0..de7b5d4 100644 --- a/debug.go +++ b/debug.go @@ -55,6 +55,12 @@ func describeRequest(op interface{}) (s string) { addComponent("name %q", f.Interface()) } + if f := v.FieldByName("OpContext"); f.IsValid() { + if meta, ok := f.Interface().(fuseops.OpContext); ok { + addComponent("PID %+v", meta.Pid) + } + } + // Handle special cases. switch typed := op.(type) { case *interruptOp: diff --git a/fuseops/ops.go b/fuseops/ops.go index 03ab376..8af3d51 100644 --- a/fuseops/ops.go +++ b/fuseops/ops.go @@ -23,6 +23,14 @@ import ( // File system //////////////////////////////////////////////////////////////////////// +// OpContext contains extra context that may be needed by some file systems. +// See https://libfuse.github.io/doxygen/structfuse__context.html as a reference. +type OpContext struct { + // PID of the process that is invoking the operation. + // Not filled in case of a writepage operation. + Pid uint32 +} + // Return statistics about the file system's capacity and available resources. // // Called by statfs(2) and friends: @@ -119,7 +127,8 @@ type LookUpInodeOp struct { // // The lookup count for the inode is implicitly incremented. See notes on // ForgetInodeOp for more information. - Entry ChildInodeEntry + Entry ChildInodeEntry + OpContext OpContext } // Refresh the attributes for an inode whose ID was previously returned in a @@ -135,6 +144,7 @@ type GetInodeAttributesOp struct { // more. Attributes InodeAttributes AttributesExpiration time.Time + OpContext OpContext } // Change attributes for an inode. @@ -159,6 +169,7 @@ type SetInodeAttributesOp struct { // ChildInodeEntry.AttributesExpiration for more. Attributes InodeAttributes AttributesExpiration time.Time + OpContext OpContext } // Decrement the reference count for an inode ID previously issued by the file @@ -205,7 +216,8 @@ type ForgetInodeOp struct { Inode InodeID // The amount to decrement the reference count. - N uint64 + N uint64 + OpContext OpContext } //////////////////////////////////////////////////////////////////////// @@ -235,7 +247,8 @@ type MkDirOp struct { // // The lookup count for the inode is implicitly incremented. See notes on // ForgetInodeOp for more information. - Entry ChildInodeEntry + Entry ChildInodeEntry + OpContext OpContext } // Create a file inode as a child of an existing directory inode. The kernel @@ -262,7 +275,8 @@ type MkNodeOp struct { // // The lookup count for the inode is implicitly incremented. See notes on // ForgetInodeOp for more information. - Entry ChildInodeEntry + Entry ChildInodeEntry + OpContext OpContext } // Create a file inode and open it. @@ -298,6 +312,7 @@ type CreateFileOp struct { // file handle. The file system must ensure this ID remains valid until a // later call to ReleaseFileHandle. Handle HandleID + OpContext OpContext } // Create a symlink inode. If the name already exists, the file system should @@ -317,7 +332,8 @@ type CreateSymlinkOp struct { // // The lookup count for the inode is implicitly incremented. See notes on // ForgetInodeOp for more information. - Entry ChildInodeEntry + Entry ChildInodeEntry + OpContext OpContext } // Create a hard link to an inode. If the name already exists, the file system @@ -337,7 +353,8 @@ type CreateLinkOp struct { // // The lookup count for the inode is implicitly incremented. See notes on // ForgetInodeOp for more information. - Entry ChildInodeEntry + Entry ChildInodeEntry + OpContext OpContext } //////////////////////////////////////////////////////////////////////// @@ -388,6 +405,7 @@ type RenameOp struct { // overwritten within it. NewParent InodeID NewName string + OpContext OpContext } // Unlink a directory from its parent. Because directories cannot have a link @@ -400,8 +418,9 @@ type RenameOp struct { type RmDirOp struct { // The ID of parent directory inode, and the name of the directory being // removed within it. - Parent InodeID - Name string + Parent InodeID + Name string + OpContext OpContext } // Unlink a file or symlink from its parent. If this brings the inode's link @@ -413,8 +432,9 @@ type RmDirOp struct { type UnlinkOp struct { // The ID of parent directory inode, and the name of the entry being removed // within it. - Parent InodeID - Name string + Parent InodeID + Name string + OpContext OpContext } //////////////////////////////////////////////////////////////////////// @@ -439,7 +459,8 @@ type OpenDirOp struct { // The handle may be supplied in future ops like ReadDirOp that contain a // directory handle. The file system must ensure this ID remains valid until // a later call to ReleaseDirHandle. - Handle HandleID + Handle HandleID + OpContext OpContext } // Read entries from a directory previously opened with OpenDir. @@ -532,6 +553,7 @@ type ReadDirOp struct { // FUSE_DIRENT_ALIGN (http://goo.gl/UziWvH) is less than the read size of // PAGE_SIZE used by fuse_readdir (cf. https://goo.gl/VajtS2). BytesRead int + OpContext OpContext } // Release a previously-minted directory handle. The kernel sends this when @@ -546,7 +568,8 @@ type ReleaseDirHandleOp struct { // The handle ID to be released. The kernel guarantees that this ID will not // be used in further calls to the file system (unless it is reissued by the // file system). - Handle HandleID + Handle HandleID + OpContext OpContext } //////////////////////////////////////////////////////////////////////// @@ -596,6 +619,8 @@ type OpenFileOp struct { // layer. This allows for filesystems whose file sizes are not known in // advance, for example, because contents are generated on the fly. UseDirectIO bool + + OpContext OpContext } // Read data from a file previously opened with CreateFile or OpenFile. @@ -626,6 +651,7 @@ type ReadFileOp struct { // // If direct IO is enabled, semantics should match those of read(2). BytesRead int + OpContext OpContext } // Write data to a file previously opened with CreateFile or OpenFile. @@ -684,7 +710,8 @@ type WriteFileOp struct { // be written, except on error (http://goo.gl/KUpwwn). This appears to be // because it uses file mmapping machinery (http://goo.gl/SGxnaN) to write a // page at a time. - Data []byte + Data []byte + OpContext OpContext } // Synchronize the current contents of an open file to storage. @@ -705,8 +732,9 @@ type WriteFileOp struct { // file (but which is not used in "real" file systems). type SyncFileOp struct { // The file and handle being sync'd. - Inode InodeID - Handle HandleID + Inode InodeID + Handle HandleID + OpContext OpContext } // Flush the current state of an open file to storage upon closing a file @@ -761,6 +789,7 @@ type FlushFileOp struct { // The file and handle being flushed. Inode InodeID Handle HandleID + OpContext OpContext } // Release a previously-minted file handle. The kernel calls this when there @@ -775,7 +804,8 @@ type ReleaseFileHandleOp struct { // The handle ID to be released. The kernel guarantees that this ID will not // be used in further calls to the file system (unless it is reissued by the // file system). - Handle HandleID + Handle HandleID + OpContext OpContext } //////////////////////////////////////////////////////////////////////// @@ -788,7 +818,8 @@ type ReadSymlinkOp struct { Inode InodeID // Set by the file system: the target of the symlink. - Target string + Target string + OpContext OpContext } //////////////////////////////////////////////////////////////////////// @@ -804,7 +835,8 @@ type RemoveXattrOp struct { Inode InodeID // The name of the extended attribute. - Name string + Name string + OpContext OpContext } // Get an extended attribute. @@ -826,6 +858,7 @@ type GetXattrOp struct { // the number of bytes that would have been read into Dst if Dst was // big enough (return ERANGE in this case). BytesRead int + OpContext OpContext } // List all the extended attributes for a file. @@ -846,6 +879,7 @@ type ListXattrOp struct { // the number of bytes that would have been read into Dst if Dst was // big enough (return ERANGE in this case). BytesRead int + OpContext OpContext } // Set an extended attribute. @@ -866,7 +900,8 @@ type SetXattrOp struct { // If Flags is 0x2, and the attribute does not exist, ENOATTR should be returned. // If Flags is 0x0, the extended attribute will be created if need be, or will // simply replace the value if the attribute exists. - Flags uint32 + Flags uint32 + OpContext OpContext } type FallocateOp struct { @@ -885,5 +920,6 @@ type FallocateOp struct { // If Mode has 0x2, deallocate space within the range specified // If Mode has 0x2, it sbould also have 0x1 (deallocate should not increase // file size) - Mode uint32 + Mode uint32 + OpContext OpContext } diff --git a/samples/in_process.go b/samples/in_process.go index 9f487db..a00b898 100644 --- a/samples/in_process.go +++ b/samples/in_process.go @@ -71,7 +71,7 @@ func (t *SampleTest) SetUp(ti *ogletest.TestInfo) { } } -// Like SetUp, but doens't panic. +// Like SetUp, but doesn't panic. func (t *SampleTest) initialize( ctx context.Context, server fuse.Server, diff --git a/samples/memfs/memfs.go b/samples/memfs/memfs.go index 2ae1078..0d50297 100644 --- a/samples/memfs/memfs.go +++ b/samples/memfs/memfs.go @@ -194,6 +194,10 @@ func (fs *memFS) StatFS( func (fs *memFS) LookUpInode( ctx context.Context, op *fuseops.LookUpInodeOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() @@ -224,6 +228,10 @@ func (fs *memFS) LookUpInode( func (fs *memFS) GetInodeAttributes( ctx context.Context, op *fuseops.GetInodeAttributesOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() @@ -243,6 +251,10 @@ func (fs *memFS) GetInodeAttributes( func (fs *memFS) SetInodeAttributes( ctx context.Context, op *fuseops.SetInodeAttributesOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() @@ -272,6 +284,10 @@ func (fs *memFS) SetInodeAttributes( func (fs *memFS) MkDir( ctx context.Context, op *fuseops.MkDirOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() @@ -314,6 +330,10 @@ func (fs *memFS) MkDir( func (fs *memFS) MkNode( ctx context.Context, op *fuseops.MkNodeOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() @@ -371,11 +391,15 @@ func (fs *memFS) createFile( func (fs *memFS) CreateFile( ctx context.Context, - op *fuseops.CreateFileOp) error { + op *fuseops.CreateFileOp) (err error) { + if op.OpContext.Pid == 0 { + // CreateFileOp should have a valid pid in context. + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() - var err error op.Entry, err = fs.createFile(op.Parent, op.Name, op.Mode) return err } @@ -383,6 +407,10 @@ func (fs *memFS) CreateFile( func (fs *memFS) CreateSymlink( ctx context.Context, op *fuseops.CreateSymlinkOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() @@ -433,6 +461,10 @@ func (fs *memFS) CreateSymlink( func (fs *memFS) CreateLink( ctx context.Context, op *fuseops.CreateLinkOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() @@ -472,6 +504,10 @@ func (fs *memFS) CreateLink( func (fs *memFS) Rename( ctx context.Context, op *fuseops.RenameOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() @@ -513,6 +549,10 @@ func (fs *memFS) Rename( func (fs *memFS) RmDir( ctx context.Context, op *fuseops.RmDirOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() @@ -545,6 +585,10 @@ func (fs *memFS) RmDir( func (fs *memFS) Unlink( ctx context.Context, op *fuseops.UnlinkOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() @@ -572,6 +616,10 @@ func (fs *memFS) Unlink( func (fs *memFS) OpenDir( ctx context.Context, op *fuseops.OpenDirOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() @@ -590,6 +638,10 @@ func (fs *memFS) OpenDir( func (fs *memFS) ReadDir( ctx context.Context, op *fuseops.ReadDirOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() @@ -605,6 +657,11 @@ func (fs *memFS) ReadDir( func (fs *memFS) OpenFile( ctx context.Context, op *fuseops.OpenFileOp) error { + if op.OpContext.Pid == 0 { + // OpenFileOp should have a valid pid in context. + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() @@ -623,6 +680,10 @@ func (fs *memFS) OpenFile( func (fs *memFS) ReadFile( ctx context.Context, op *fuseops.ReadFileOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() @@ -644,6 +705,10 @@ func (fs *memFS) ReadFile( func (fs *memFS) WriteFile( ctx context.Context, op *fuseops.WriteFileOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() @@ -656,9 +721,23 @@ func (fs *memFS) WriteFile( return err } +func (fs *memFS) FlushFile( + ctx context.Context, + op *fuseops.FlushFileOp) (err error) { + if op.OpContext.Pid == 0 { + // FlushFileOp should have a valid pid in context. + return fuse.EINVAL + } + return +} + func (fs *memFS) ReadSymlink( ctx context.Context, op *fuseops.ReadSymlinkOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() @@ -673,6 +752,10 @@ func (fs *memFS) ReadSymlink( func (fs *memFS) GetXattr(ctx context.Context, op *fuseops.GetXattrOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() @@ -693,6 +776,10 @@ func (fs *memFS) GetXattr(ctx context.Context, func (fs *memFS) ListXattr(ctx context.Context, op *fuseops.ListXattrOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() @@ -716,6 +803,10 @@ func (fs *memFS) ListXattr(ctx context.Context, func (fs *memFS) RemoveXattr(ctx context.Context, op *fuseops.RemoveXattrOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() inode := fs.getInodeOrDie(op.Inode) @@ -730,6 +821,10 @@ func (fs *memFS) RemoveXattr(ctx context.Context, func (fs *memFS) SetXattr(ctx context.Context, op *fuseops.SetXattrOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() inode := fs.getInodeOrDie(op.Inode) @@ -755,6 +850,10 @@ func (fs *memFS) SetXattr(ctx context.Context, func (fs *memFS) Fallocate(ctx context.Context, op *fuseops.FallocateOp) error { + if op.OpContext.Pid == 0 { + return fuse.EINVAL + } + fs.mu.Lock() defer fs.mu.Unlock() inode := fs.getInodeOrDie(op.Inode) diff --git a/samples/memfs/memfs_test.go b/samples/memfs/memfs_test.go index d2f0a1d..68f7432 100644 --- a/samples/memfs/memfs_test.go +++ b/samples/memfs/memfs_test.go @@ -97,6 +97,9 @@ type memFSTest struct { } func (t *memFSTest) SetUp(ti *TestInfo) { + // Disable writeback caching so that pid is always available in OpContext + t.MountConfig.DisableWritebackCaching = true + t.Server = memfs.NewMemFS(currentUid(), currentGid()) t.SampleTest.SetUp(ti) }