Require FileSystem methods to call Op.Respond.

And provide a helper to make it convenient to do so.

Having the server implementation call Respond makes it unnecessarily tricky to
implement FileSystem methods that continue computations in the background and
return immediately, for example enqueuing writes/flushes for a worker
goroutine.
geesefs-0-30-9
Aaron Jacobs 2015-03-25 10:00:58 +11:00
commit 2c10dd18ca
6 changed files with 242 additions and 112 deletions

View File

@ -26,39 +26,67 @@ import (
// loop" that switches on op types, instead receiving typed method calls // loop" that switches on op types, instead receiving typed method calls
// directly. // directly.
// //
// Each method should fill in appropriate response fields for the supplied op // Each method is responsible for calling Respond on the supplied op.
// and return an error status, but not call Repand.
// //
// See NotImplementedFileSystem for a convenient way to embed default // See NotImplementedFileSystem for a convenient way to embed default
// implementations for methods you don't care about. // implementations for methods you don't care about.
type FileSystem interface { type FileSystem interface {
Init(*fuseops.InitOp) error Init(*fuseops.InitOp)
LookUpInode(*fuseops.LookUpInodeOp) error LookUpInode(*fuseops.LookUpInodeOp)
GetInodeAttributes(*fuseops.GetInodeAttributesOp) error GetInodeAttributes(*fuseops.GetInodeAttributesOp)
SetInodeAttributes(*fuseops.SetInodeAttributesOp) error SetInodeAttributes(*fuseops.SetInodeAttributesOp)
ForgetInode(*fuseops.ForgetInodeOp) error ForgetInode(*fuseops.ForgetInodeOp)
MkDir(*fuseops.MkDirOp) error MkDir(*fuseops.MkDirOp)
CreateFile(*fuseops.CreateFileOp) error CreateFile(*fuseops.CreateFileOp)
RmDir(*fuseops.RmDirOp) error RmDir(*fuseops.RmDirOp)
Unlink(*fuseops.UnlinkOp) error Unlink(*fuseops.UnlinkOp)
OpenDir(*fuseops.OpenDirOp) error OpenDir(*fuseops.OpenDirOp)
ReadDir(*fuseops.ReadDirOp) error ReadDir(*fuseops.ReadDirOp)
ReleaseDirHandle(*fuseops.ReleaseDirHandleOp) error ReleaseDirHandle(*fuseops.ReleaseDirHandleOp)
OpenFile(*fuseops.OpenFileOp) error OpenFile(*fuseops.OpenFileOp)
ReadFile(*fuseops.ReadFileOp) error ReadFile(*fuseops.ReadFileOp)
WriteFile(*fuseops.WriteFileOp) error WriteFile(*fuseops.WriteFileOp)
SyncFile(*fuseops.SyncFileOp) error SyncFile(*fuseops.SyncFileOp)
FlushFile(*fuseops.FlushFileOp) error FlushFile(*fuseops.FlushFileOp)
ReleaseFileHandle(*fuseops.ReleaseFileHandleOp) error ReleaseFileHandle(*fuseops.ReleaseFileHandleOp)
} }
// Create a fuse.Server that serves ops by calling the associated FileSystem // Create a fuse.Server that handles ops by calling the associated FileSystem
// method and then calling Op.Respond with the resulting error. Unsupported ops // method.Respond with the resulting error. Unsupported ops are responded to
// are responded to directly with ENOSYS. // directly with ENOSYS.
//
// FileSystem methods are called ine exactly the order of supported ops
// received by the connection, on a single goroutine. The methods should
// probably not block, instead continuing long-running operations in the
// background. Note however that there are subtleties here: for example, you
// probably want to serialize the order of write and flush operations.
func NewFileSystemServer(fs FileSystem) fuse.Server { func NewFileSystemServer(fs FileSystem) fuse.Server {
return fileSystemServer{fs} return fileSystemServer{fs}
} }
// A convenience function that makes it easy to ensure you respond to an
// operation when a FileSystem method returns. Responds to op with the current
// value of *err.
//
// For example:
//
// func (fs *myFS) ReadFile(op *fuseops.ReadFileOp) {
// var err error
// defer fuseutil.RespondToOp(op, &err)
//
// if err = fs.frobnicate(); err != nil {
// err = fmt.Errorf("frobnicate: %v", err)
// return
// }
//
// // Lots more manipulation of err, and return paths.
// // [...]
// }
//
func RespondToOp(op fuseops.Op, err *error) {
op.Respond(*err)
}
type fileSystemServer struct { type fileSystemServer struct {
fs FileSystem fs FileSystem
} }
@ -79,58 +107,58 @@ func (s fileSystemServer) ServeOps(c *fuse.Connection) {
op.Respond(fuse.ENOSYS) op.Respond(fuse.ENOSYS)
case *fuseops.InitOp: case *fuseops.InitOp:
op.Respond(s.fs.Init(typed)) s.fs.Init(typed)
case *fuseops.LookUpInodeOp: case *fuseops.LookUpInodeOp:
op.Respond(s.fs.LookUpInode(typed)) s.fs.LookUpInode(typed)
case *fuseops.GetInodeAttributesOp: case *fuseops.GetInodeAttributesOp:
op.Respond(s.fs.GetInodeAttributes(typed)) s.fs.GetInodeAttributes(typed)
case *fuseops.SetInodeAttributesOp: case *fuseops.SetInodeAttributesOp:
op.Respond(s.fs.SetInodeAttributes(typed)) s.fs.SetInodeAttributes(typed)
case *fuseops.ForgetInodeOp: case *fuseops.ForgetInodeOp:
op.Respond(s.fs.ForgetInode(typed)) s.fs.ForgetInode(typed)
case *fuseops.MkDirOp: case *fuseops.MkDirOp:
op.Respond(s.fs.MkDir(typed)) s.fs.MkDir(typed)
case *fuseops.CreateFileOp: case *fuseops.CreateFileOp:
op.Respond(s.fs.CreateFile(typed)) s.fs.CreateFile(typed)
case *fuseops.RmDirOp: case *fuseops.RmDirOp:
op.Respond(s.fs.RmDir(typed)) s.fs.RmDir(typed)
case *fuseops.UnlinkOp: case *fuseops.UnlinkOp:
op.Respond(s.fs.Unlink(typed)) s.fs.Unlink(typed)
case *fuseops.OpenDirOp: case *fuseops.OpenDirOp:
op.Respond(s.fs.OpenDir(typed)) s.fs.OpenDir(typed)
case *fuseops.ReadDirOp: case *fuseops.ReadDirOp:
op.Respond(s.fs.ReadDir(typed)) s.fs.ReadDir(typed)
case *fuseops.ReleaseDirHandleOp: case *fuseops.ReleaseDirHandleOp:
op.Respond(s.fs.ReleaseDirHandle(typed)) s.fs.ReleaseDirHandle(typed)
case *fuseops.OpenFileOp: case *fuseops.OpenFileOp:
op.Respond(s.fs.OpenFile(typed)) s.fs.OpenFile(typed)
case *fuseops.ReadFileOp: case *fuseops.ReadFileOp:
op.Respond(s.fs.ReadFile(typed)) s.fs.ReadFile(typed)
case *fuseops.WriteFileOp: case *fuseops.WriteFileOp:
op.Respond(s.fs.WriteFile(typed)) s.fs.WriteFile(typed)
case *fuseops.SyncFileOp: case *fuseops.SyncFileOp:
op.Respond(s.fs.SyncFile(typed)) s.fs.SyncFile(typed)
case *fuseops.FlushFileOp: case *fuseops.FlushFileOp:
op.Respond(s.fs.FlushFile(typed)) s.fs.FlushFile(typed)
case *fuseops.ReleaseFileHandleOp: case *fuseops.ReleaseFileHandleOp:
op.Respond(s.fs.ReleaseFileHandle(typed)) s.fs.ReleaseFileHandle(typed)
} }
} }
} }

View File

@ -19,7 +19,7 @@ import (
"github.com/jacobsa/fuse/fuseops" "github.com/jacobsa/fuse/fuseops"
) )
// A FileSystem that returns fuse.ENOSYS for all methods. Embed this in your // A FileSystem that responds to all ops with fuse.ENOSYS. Embed this in your
// struct to inherit default implementations for the methods you don't care // struct to inherit default implementations for the methods you don't care
// about, ensuring your struct will continue to implement FileSystem even as // about, ensuring your struct will continue to implement FileSystem even as
// new methods are added. // new methods are added.
@ -29,91 +29,91 @@ type NotImplementedFileSystem struct {
var _ FileSystem = &NotImplementedFileSystem{} var _ FileSystem = &NotImplementedFileSystem{}
func (fs *NotImplementedFileSystem) Init( func (fs *NotImplementedFileSystem) Init(
op *fuseops.InitOp) error { op *fuseops.InitOp) {
return fuse.ENOSYS op.Respond(fuse.ENOSYS)
} }
func (fs *NotImplementedFileSystem) LookUpInode( func (fs *NotImplementedFileSystem) LookUpInode(
op *fuseops.LookUpInodeOp) error { op *fuseops.LookUpInodeOp) {
return fuse.ENOSYS op.Respond(fuse.ENOSYS)
} }
func (fs *NotImplementedFileSystem) GetInodeAttributes( func (fs *NotImplementedFileSystem) GetInodeAttributes(
op *fuseops.GetInodeAttributesOp) error { op *fuseops.GetInodeAttributesOp) {
return fuse.ENOSYS op.Respond(fuse.ENOSYS)
} }
func (fs *NotImplementedFileSystem) SetInodeAttributes( func (fs *NotImplementedFileSystem) SetInodeAttributes(
op *fuseops.SetInodeAttributesOp) error { op *fuseops.SetInodeAttributesOp) {
return fuse.ENOSYS op.Respond(fuse.ENOSYS)
} }
func (fs *NotImplementedFileSystem) ForgetInode( func (fs *NotImplementedFileSystem) ForgetInode(
op *fuseops.ForgetInodeOp) error { op *fuseops.ForgetInodeOp) {
return fuse.ENOSYS op.Respond(fuse.ENOSYS)
} }
func (fs *NotImplementedFileSystem) MkDir( func (fs *NotImplementedFileSystem) MkDir(
op *fuseops.MkDirOp) error { op *fuseops.MkDirOp) {
return fuse.ENOSYS op.Respond(fuse.ENOSYS)
} }
func (fs *NotImplementedFileSystem) CreateFile( func (fs *NotImplementedFileSystem) CreateFile(
op *fuseops.CreateFileOp) error { op *fuseops.CreateFileOp) {
return fuse.ENOSYS op.Respond(fuse.ENOSYS)
} }
func (fs *NotImplementedFileSystem) RmDir( func (fs *NotImplementedFileSystem) RmDir(
op *fuseops.RmDirOp) error { op *fuseops.RmDirOp) {
return fuse.ENOSYS op.Respond(fuse.ENOSYS)
} }
func (fs *NotImplementedFileSystem) Unlink( func (fs *NotImplementedFileSystem) Unlink(
op *fuseops.UnlinkOp) error { op *fuseops.UnlinkOp) {
return fuse.ENOSYS op.Respond(fuse.ENOSYS)
} }
func (fs *NotImplementedFileSystem) OpenDir( func (fs *NotImplementedFileSystem) OpenDir(
op *fuseops.OpenDirOp) error { op *fuseops.OpenDirOp) {
return fuse.ENOSYS op.Respond(fuse.ENOSYS)
} }
func (fs *NotImplementedFileSystem) ReadDir( func (fs *NotImplementedFileSystem) ReadDir(
op *fuseops.ReadDirOp) error { op *fuseops.ReadDirOp) {
return fuse.ENOSYS op.Respond(fuse.ENOSYS)
} }
func (fs *NotImplementedFileSystem) ReleaseDirHandle( func (fs *NotImplementedFileSystem) ReleaseDirHandle(
op *fuseops.ReleaseDirHandleOp) error { op *fuseops.ReleaseDirHandleOp) {
return fuse.ENOSYS op.Respond(fuse.ENOSYS)
} }
func (fs *NotImplementedFileSystem) OpenFile( func (fs *NotImplementedFileSystem) OpenFile(
op *fuseops.OpenFileOp) error { op *fuseops.OpenFileOp) {
return fuse.ENOSYS op.Respond(fuse.ENOSYS)
} }
func (fs *NotImplementedFileSystem) ReadFile( func (fs *NotImplementedFileSystem) ReadFile(
op *fuseops.ReadFileOp) error { op *fuseops.ReadFileOp) {
return fuse.ENOSYS op.Respond(fuse.ENOSYS)
} }
func (fs *NotImplementedFileSystem) WriteFile( func (fs *NotImplementedFileSystem) WriteFile(
op *fuseops.WriteFileOp) error { op *fuseops.WriteFileOp) {
return fuse.ENOSYS op.Respond(fuse.ENOSYS)
} }
func (fs *NotImplementedFileSystem) SyncFile( func (fs *NotImplementedFileSystem) SyncFile(
op *fuseops.SyncFileOp) error { op *fuseops.SyncFileOp) {
return fuse.ENOSYS op.Respond(fuse.ENOSYS)
} }
func (fs *NotImplementedFileSystem) FlushFile( func (fs *NotImplementedFileSystem) FlushFile(
op *fuseops.FlushFileOp) error { op *fuseops.FlushFileOp) {
return fuse.ENOSYS op.Respond(fuse.ENOSYS)
} }
func (fs *NotImplementedFileSystem) ReleaseFileHandle( func (fs *NotImplementedFileSystem) ReleaseFileHandle(
op *fuseops.ReleaseFileHandleOp) error { op *fuseops.ReleaseFileHandleOp) {
return fuse.ENOSYS op.Respond(fuse.ENOSYS)
} }

View File

@ -239,13 +239,19 @@ func (fs *cachingFS) SetMtime(mtime time.Time) {
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
func (fs *cachingFS) Init( func (fs *cachingFS) Init(
op *fuseops.InitOp) (err error) { op *fuseops.InitOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
return return
} }
// LOCKS_EXCLUDED(fs.mu) // LOCKS_EXCLUDED(fs.mu)
func (fs *cachingFS) LookUpInode( func (fs *cachingFS) LookUpInode(
op *fuseops.LookUpInodeOp) (err error) { op *fuseops.LookUpInodeOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.Lock() fs.mu.Lock()
defer fs.mu.Unlock() defer fs.mu.Unlock()
@ -299,7 +305,10 @@ func (fs *cachingFS) LookUpInode(
// LOCKS_EXCLUDED(fs.mu) // LOCKS_EXCLUDED(fs.mu)
func (fs *cachingFS) GetInodeAttributes( func (fs *cachingFS) GetInodeAttributes(
op *fuseops.GetInodeAttributesOp) (err error) { op *fuseops.GetInodeAttributesOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.Lock() fs.mu.Lock()
defer fs.mu.Unlock() defer fs.mu.Unlock()
@ -328,11 +337,17 @@ func (fs *cachingFS) GetInodeAttributes(
} }
func (fs *cachingFS) OpenDir( func (fs *cachingFS) OpenDir(
op *fuseops.OpenDirOp) (err error) { op *fuseops.OpenDirOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
return return
} }
func (fs *cachingFS) OpenFile( func (fs *cachingFS) OpenFile(
op *fuseops.OpenFileOp) (err error) { op *fuseops.OpenFileOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
return return
} }

View File

@ -93,12 +93,18 @@ func (fs *flushFS) barAttributes() fuseops.InodeAttributes {
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
func (fs *flushFS) Init( func (fs *flushFS) Init(
op *fuseops.InitOp) (err error) { op *fuseops.InitOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
return return
} }
func (fs *flushFS) LookUpInode( func (fs *flushFS) LookUpInode(
op *fuseops.LookUpInodeOp) (err error) { op *fuseops.LookUpInodeOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.Lock() fs.mu.Lock()
defer fs.mu.Unlock() defer fs.mu.Unlock()
@ -131,7 +137,10 @@ func (fs *flushFS) LookUpInode(
} }
func (fs *flushFS) GetInodeAttributes( func (fs *flushFS) GetInodeAttributes(
op *fuseops.GetInodeAttributesOp) (err error) { op *fuseops.GetInodeAttributesOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.Lock() fs.mu.Lock()
defer fs.mu.Unlock() defer fs.mu.Unlock()
@ -155,7 +164,10 @@ func (fs *flushFS) GetInodeAttributes(
} }
func (fs *flushFS) OpenFile( func (fs *flushFS) OpenFile(
op *fuseops.OpenFileOp) (err error) { op *fuseops.OpenFileOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.Lock() fs.mu.Lock()
defer fs.mu.Unlock() defer fs.mu.Unlock()
@ -169,7 +181,10 @@ func (fs *flushFS) OpenFile(
} }
func (fs *flushFS) ReadFile( func (fs *flushFS) ReadFile(
op *fuseops.ReadFileOp) (err error) { op *fuseops.ReadFileOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.Lock() fs.mu.Lock()
defer fs.mu.Unlock() defer fs.mu.Unlock()
@ -186,7 +201,10 @@ func (fs *flushFS) ReadFile(
} }
func (fs *flushFS) WriteFile( func (fs *flushFS) WriteFile(
op *fuseops.WriteFileOp) (err error) { op *fuseops.WriteFileOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.Lock() fs.mu.Lock()
defer fs.mu.Unlock() defer fs.mu.Unlock()
@ -209,7 +227,10 @@ func (fs *flushFS) WriteFile(
} }
func (fs *flushFS) SyncFile( func (fs *flushFS) SyncFile(
op *fuseops.SyncFileOp) (err error) { op *fuseops.SyncFileOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.Lock() fs.mu.Lock()
defer fs.mu.Unlock() defer fs.mu.Unlock()
@ -218,7 +239,10 @@ func (fs *flushFS) SyncFile(
} }
func (fs *flushFS) FlushFile( func (fs *flushFS) FlushFile(
op *fuseops.FlushFileOp) (err error) { op *fuseops.FlushFileOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.Lock() fs.mu.Lock()
defer fs.mu.Unlock() defer fs.mu.Unlock()
@ -227,7 +251,10 @@ func (fs *flushFS) FlushFile(
} }
func (fs *flushFS) OpenDir( func (fs *flushFS) OpenDir(
op *fuseops.OpenDirOp) (err error) { op *fuseops.OpenDirOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.Lock() fs.mu.Lock()
defer fs.mu.Unlock() defer fs.mu.Unlock()

View File

@ -147,11 +147,17 @@ func (fs *helloFS) patchAttributes(
attr.Crtime = now attr.Crtime = now
} }
func (fs *helloFS) Init(op *fuseops.InitOp) (err error) { func (fs *helloFS) Init(op *fuseops.InitOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
return return
} }
func (fs *helloFS) LookUpInode(op *fuseops.LookUpInodeOp) (err error) { func (fs *helloFS) LookUpInode(op *fuseops.LookUpInodeOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
// Find the info for the parent. // Find the info for the parent.
parentInfo, ok := gInodeInfo[op.Parent] parentInfo, ok := gInodeInfo[op.Parent]
if !ok { if !ok {
@ -176,7 +182,10 @@ func (fs *helloFS) LookUpInode(op *fuseops.LookUpInodeOp) (err error) {
} }
func (fs *helloFS) GetInodeAttributes( func (fs *helloFS) GetInodeAttributes(
op *fuseops.GetInodeAttributesOp) (err error) { op *fuseops.GetInodeAttributesOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
// Find the info for this inode. // Find the info for this inode.
info, ok := gInodeInfo[op.Inode] info, ok := gInodeInfo[op.Inode]
if !ok { if !ok {
@ -194,13 +203,19 @@ func (fs *helloFS) GetInodeAttributes(
} }
func (fs *helloFS) OpenDir( func (fs *helloFS) OpenDir(
op *fuseops.OpenDirOp) (err error) { op *fuseops.OpenDirOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
// Allow opening any directory. // Allow opening any directory.
return return
} }
func (fs *helloFS) ReadDir( func (fs *helloFS) ReadDir(
op *fuseops.ReadDirOp) (err error) { op *fuseops.ReadDirOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
// Find the info for this inode. // Find the info for this inode.
info, ok := gInodeInfo[op.Inode] info, ok := gInodeInfo[op.Inode]
if !ok { if !ok {
@ -236,13 +251,19 @@ func (fs *helloFS) ReadDir(
} }
func (fs *helloFS) OpenFile( func (fs *helloFS) OpenFile(
op *fuseops.OpenFileOp) (err error) { op *fuseops.OpenFileOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
// Allow opening any file. // Allow opening any file.
return return
} }
func (fs *helloFS) ReadFile( func (fs *helloFS) ReadFile(
op *fuseops.ReadFileOp) (err error) { op *fuseops.ReadFileOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
// Let io.ReaderAt deal with the semantics. // Let io.ReaderAt deal with the semantics.
reader := strings.NewReader("Hello, world!") reader := strings.NewReader("Hello, world!")

View File

@ -200,12 +200,18 @@ func (fs *memFS) deallocateInode(id fuseops.InodeID) {
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
func (fs *memFS) Init( func (fs *memFS) Init(
op *fuseops.InitOp) (err error) { op *fuseops.InitOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
return return
} }
func (fs *memFS) LookUpInode( func (fs *memFS) LookUpInode(
op *fuseops.LookUpInodeOp) (err error) { op *fuseops.LookUpInodeOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.RLock() fs.mu.RLock()
defer fs.mu.RUnlock() defer fs.mu.RUnlock()
@ -237,7 +243,10 @@ func (fs *memFS) LookUpInode(
} }
func (fs *memFS) GetInodeAttributes( func (fs *memFS) GetInodeAttributes(
op *fuseops.GetInodeAttributesOp) (err error) { op *fuseops.GetInodeAttributesOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.RLock() fs.mu.RLock()
defer fs.mu.RUnlock() defer fs.mu.RUnlock()
@ -256,7 +265,10 @@ func (fs *memFS) GetInodeAttributes(
} }
func (fs *memFS) SetInodeAttributes( func (fs *memFS) SetInodeAttributes(
op *fuseops.SetInodeAttributesOp) (err error) { op *fuseops.SetInodeAttributesOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.RLock() fs.mu.RLock()
defer fs.mu.RUnlock() defer fs.mu.RUnlock()
@ -278,7 +290,10 @@ func (fs *memFS) SetInodeAttributes(
} }
func (fs *memFS) MkDir( func (fs *memFS) MkDir(
op *fuseops.MkDirOp) (err error) { op *fuseops.MkDirOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.Lock() fs.mu.Lock()
defer fs.mu.Unlock() defer fs.mu.Unlock()
@ -315,7 +330,10 @@ func (fs *memFS) MkDir(
} }
func (fs *memFS) CreateFile( func (fs *memFS) CreateFile(
op *fuseops.CreateFileOp) (err error) { op *fuseops.CreateFileOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.Lock() fs.mu.Lock()
defer fs.mu.Unlock() defer fs.mu.Unlock()
@ -359,7 +377,10 @@ func (fs *memFS) CreateFile(
} }
func (fs *memFS) RmDir( func (fs *memFS) RmDir(
op *fuseops.RmDirOp) (err error) { op *fuseops.RmDirOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.Lock() fs.mu.Lock()
defer fs.mu.Unlock() defer fs.mu.Unlock()
@ -394,7 +415,10 @@ func (fs *memFS) RmDir(
} }
func (fs *memFS) Unlink( func (fs *memFS) Unlink(
op *fuseops.UnlinkOp) (err error) { op *fuseops.UnlinkOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.Lock() fs.mu.Lock()
defer fs.mu.Unlock() defer fs.mu.Unlock()
@ -423,7 +447,10 @@ func (fs *memFS) Unlink(
} }
func (fs *memFS) OpenDir( func (fs *memFS) OpenDir(
op *fuseops.OpenDirOp) (err error) { op *fuseops.OpenDirOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.RLock() fs.mu.RLock()
defer fs.mu.RUnlock() defer fs.mu.RUnlock()
@ -441,7 +468,10 @@ func (fs *memFS) OpenDir(
} }
func (fs *memFS) ReadDir( func (fs *memFS) ReadDir(
op *fuseops.ReadDirOp) (err error) { op *fuseops.ReadDirOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.RLock() fs.mu.RLock()
defer fs.mu.RUnlock() defer fs.mu.RUnlock()
@ -460,7 +490,10 @@ func (fs *memFS) ReadDir(
} }
func (fs *memFS) OpenFile( func (fs *memFS) OpenFile(
op *fuseops.OpenFileOp) (err error) { op *fuseops.OpenFileOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.RLock() fs.mu.RLock()
defer fs.mu.RUnlock() defer fs.mu.RUnlock()
@ -478,7 +511,10 @@ func (fs *memFS) OpenFile(
} }
func (fs *memFS) ReadFile( func (fs *memFS) ReadFile(
op *fuseops.ReadFileOp) (err error) { op *fuseops.ReadFileOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.RLock() fs.mu.RLock()
defer fs.mu.RUnlock() defer fs.mu.RUnlock()
@ -500,7 +536,10 @@ func (fs *memFS) ReadFile(
} }
func (fs *memFS) WriteFile( func (fs *memFS) WriteFile(
op *fuseops.WriteFileOp) (err error) { op *fuseops.WriteFileOp) {
var err error
defer fuseutil.RespondToOp(op, &err)
fs.mu.RLock() fs.mu.RLock()
defer fs.mu.RUnlock() defer fs.mu.RUnlock()