From 00809e98fe069a3df2f1452c0fe539e0c85c74d0 Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Wed, 25 Mar 2015 09:16:03 +1100 Subject: [PATCH 1/5] Added a FileSystem interface and declared a function that transforms it. --- fuseutil/file_system.go | 53 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 fuseutil/file_system.go diff --git a/fuseutil/file_system.go b/fuseutil/file_system.go new file mode 100644 index 0000000..288bf9d --- /dev/null +++ b/fuseutil/file_system.go @@ -0,0 +1,53 @@ +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fuseutil + +import ( + "github.com/jacobsa/fuse" + "github.com/jacobsa/fuse/fuseops" +) + +// An interface with a method for each op type in the fuseops package. This can +// be used in conjunction with NewFileSystemServer to avoid writing a "dispatch +// loop" that switches on op types, instead receiving typed method calls +// directly. +// +// Each method should fill in appropriate response fields for the supplied op +// and return an error status, but not call Repand. +type FileSystem interface { + Init(*fuseops.InitOp) error + LookUpInode(*fuseops.LookUpInodeOp) error + GetInodeAttributes(*fuseops.GetInodeAttributesOp) error + SetInodeAttributes(*fuseops.SetInodeAttributesOp) error + ForgetInode(*fuseops.ForgetInodeOp) error + MkDir(*fuseops.MkDirOp) error + CreateFile(*fuseops.CreateFileOp) error + RmDir(*fuseops.RmDirOp) error + Unlink(*fuseops.UnlinkOp) error + OpenDir(*fuseops.OpenDirOp) error + ReadDir(*fuseops.ReadDirOp) error + ReleaseDirHandle(*fuseops.ReleaseDirHandleOp) error + OpenFile(*fuseops.OpenFileOp) error + ReadFile(*fuseops.ReadFileOp) error + WriteFile(*fuseops.WriteFileOp) error + SyncFile(*fuseops.SyncFileOp) error + FlushFile(*fuseops.FlushFileOp) error + ReleaseFileHandle(*fuseops.ReleaseFileHandleOp) error +} + +// Create a fuse.Server that serves ops by calling the associated FileSystem +// method and then calling Op.Respond with the resulting error. Unsupported ops +// are responded to directly with ENOSYS. +func NewFileSystemServer(fs FileSystem) fuse.Server From 485f5d64fc7a8c7447c31a699a64c5334ebdec99 Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Wed, 25 Mar 2015 09:17:58 +1100 Subject: [PATCH 2/5] Declared NotImplementedFileSystem. --- fuseutil/file_system.go | 3 +++ fuseutil/not_implemented_file_system.go | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 fuseutil/not_implemented_file_system.go diff --git a/fuseutil/file_system.go b/fuseutil/file_system.go index 288bf9d..612a766 100644 --- a/fuseutil/file_system.go +++ b/fuseutil/file_system.go @@ -26,6 +26,9 @@ import ( // // Each method should fill in appropriate response fields for the supplied op // and return an error status, but not call Repand. +// +// See NotImplementedFileSystem for a convenient way to embed default +// implementations for methods you don't care about. type FileSystem interface { Init(*fuseops.InitOp) error LookUpInode(*fuseops.LookUpInodeOp) error diff --git a/fuseutil/not_implemented_file_system.go b/fuseutil/not_implemented_file_system.go new file mode 100644 index 0000000..0eb71b2 --- /dev/null +++ b/fuseutil/not_implemented_file_system.go @@ -0,0 +1,24 @@ +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fuseutil + +// A FileSystem that returns ENOSYS for all methods. Embed this in your struct +// to inherit default implementations for the methods you don't care about, +// ensuring your struct will continue to implement FileSystem even as new +// methods are added. +type NotImplementedFileSystem struct { +} + +var _ FileSystem = &NotImplementedFileSystem{} From cdfc7045b56c6f4589898cdd6c829b9353b8541e Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Wed, 25 Mar 2015 09:18:56 +1100 Subject: [PATCH 3/5] Added a callout to fuseutil.NewFileSystemServer. --- doc.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc.go b/doc.go index 1f8f8a6..47aca08 100644 --- a/doc.go +++ b/doc.go @@ -19,7 +19,10 @@ // * The fuseops package, which defines the operations that fuse might send // to your userspace daemon. // -// * The Server interface, which a type in your daemon must implement. +// * The Server interface, which your daemon must implement. +// +// * fuseutil.NewFileSystemServer, which offers a convenient way to implement +// the Server interface. // // * Mount, a function that allows for mounting a Server as a file system. // From 579e3f648e386390601d6dee2793384fa8b1cb62 Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Wed, 25 Mar 2015 09:20:54 +1100 Subject: [PATCH 4/5] Added NotImplementedFileSystem methods. --- fuseutil/not_implemented_file_system.go | 103 +++++++++++++++++++++++- 1 file changed, 99 insertions(+), 4 deletions(-) diff --git a/fuseutil/not_implemented_file_system.go b/fuseutil/not_implemented_file_system.go index 0eb71b2..57fd78b 100644 --- a/fuseutil/not_implemented_file_system.go +++ b/fuseutil/not_implemented_file_system.go @@ -14,11 +14,106 @@ package fuseutil -// A FileSystem that returns ENOSYS for all methods. Embed this in your struct -// to inherit default implementations for the methods you don't care about, -// ensuring your struct will continue to implement FileSystem even as new -// methods are added. +import ( + "github.com/jacobsa/fuse" + "github.com/jacobsa/fuse/fuseops" +) + +// A FileSystem that returns fuse.ENOSYS for all methods. Embed this in your +// struct to inherit default implementations for the methods you don't care +// about, ensuring your struct will continue to implement FileSystem even as +// new methods are added. type NotImplementedFileSystem struct { } var _ FileSystem = &NotImplementedFileSystem{} + +func (fs *NotImplementedFileSystem) Init( + op *fuseops.InitOp) error { + return fuse.ENOSYS +} + +func (fs *NotImplementedFileSystem) LookUpInode( + op *fuseops.LookUpInodeOp) error { + return fuse.ENOSYS +} + +func (fs *NotImplementedFileSystem) GetInodeAttributes( + op *fuseops.GetInodeAttributesOp) error { + return fuse.ENOSYS +} + +func (fs *NotImplementedFileSystem) SetInodeAttributes( + op *fuseops.SetInodeAttributesOp) error { + return fuse.ENOSYS +} + +func (fs *NotImplementedFileSystem) ForgetInode( + op *fuseops.ForgetInodeOp) error { + return fuse.ENOSYS +} + +func (fs *NotImplementedFileSystem) MkDir( + op *fuseops.MkDirOp) error { + return fuse.ENOSYS +} + +func (fs *NotImplementedFileSystem) CreateFile( + op *fuseops.CreateFileOp) error { + return fuse.ENOSYS +} + +func (fs *NotImplementedFileSystem) RmDir( + op *fuseops.RmDirOp) error { + return fuse.ENOSYS +} + +func (fs *NotImplementedFileSystem) Unlink( + op *fuseops.UnlinkOp) error { + return fuse.ENOSYS +} + +func (fs *NotImplementedFileSystem) OpenDir( + op *fuseops.OpenDirOp) error { + return fuse.ENOSYS +} + +func (fs *NotImplementedFileSystem) ReadDir( + op *fuseops.ReadDirOp) error { + return fuse.ENOSYS +} + +func (fs *NotImplementedFileSystem) ReleaseDirHandle( + op *fuseops.ReleaseDirHandleOp) error { + return fuse.ENOSYS +} + +func (fs *NotImplementedFileSystem) OpenFile( + op *fuseops.OpenFileOp) error { + return fuse.ENOSYS +} + +func (fs *NotImplementedFileSystem) ReadFile( + op *fuseops.ReadFileOp) error { + return fuse.ENOSYS +} + +func (fs *NotImplementedFileSystem) WriteFile( + op *fuseops.WriteFileOp) error { + return fuse.ENOSYS +} + +func (fs *NotImplementedFileSystem) SyncFile( + op *fuseops.SyncFileOp) error { + return fuse.ENOSYS +} + +func (fs *NotImplementedFileSystem) FlushFile( + op *fuseops.FlushFileOp) error { + return fuse.ENOSYS +} + +func (fs *NotImplementedFileSystem) ReleaseFileHandle( + op *fuseops.ReleaseFileHandleOp) error { + return fuse.ENOSYS +} From 2c0b99bdceb3a7bfb6126ac7a45263f55ca275f3 Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Wed, 25 Mar 2015 09:24:44 +1100 Subject: [PATCH 5/5] Implemented NewFileSystemServer. --- fuseutil/file_system.go | 82 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/fuseutil/file_system.go b/fuseutil/file_system.go index 612a766..49eb1a7 100644 --- a/fuseutil/file_system.go +++ b/fuseutil/file_system.go @@ -15,6 +15,8 @@ package fuseutil import ( + "io" + "github.com/jacobsa/fuse" "github.com/jacobsa/fuse/fuseops" ) @@ -53,4 +55,82 @@ type FileSystem interface { // Create a fuse.Server that serves ops by calling the associated FileSystem // method and then calling Op.Respond with the resulting error. Unsupported ops // are responded to directly with ENOSYS. -func NewFileSystemServer(fs FileSystem) fuse.Server +func NewFileSystemServer(fs FileSystem) fuse.Server { + return fileSystemServer{fs} +} + +type fileSystemServer struct { + fs FileSystem +} + +func (s fileSystemServer) ServeOps(c *fuse.Connection) { + for { + op, err := c.ReadOp() + if err == io.EOF { + break + } + + if err != nil { + panic(err) + } + + switch typed := op.(type) { + default: + op.Respond(fuse.ENOSYS) + + case *fuseops.InitOp: + op.Respond(s.fs.Init(typed)) + + case *fuseops.LookUpInodeOp: + op.Respond(s.fs.LookUpInode(typed)) + + case *fuseops.GetInodeAttributesOp: + op.Respond(s.fs.GetInodeAttributes(typed)) + + case *fuseops.SetInodeAttributesOp: + op.Respond(s.fs.SetInodeAttributes(typed)) + + case *fuseops.ForgetInodeOp: + op.Respond(s.fs.ForgetInode(typed)) + + case *fuseops.MkDirOp: + op.Respond(s.fs.MkDir(typed)) + + case *fuseops.CreateFileOp: + op.Respond(s.fs.CreateFile(typed)) + + case *fuseops.RmDirOp: + op.Respond(s.fs.RmDir(typed)) + + case *fuseops.UnlinkOp: + op.Respond(s.fs.Unlink(typed)) + + case *fuseops.OpenDirOp: + op.Respond(s.fs.OpenDir(typed)) + + case *fuseops.ReadDirOp: + op.Respond(s.fs.ReadDir(typed)) + + case *fuseops.ReleaseDirHandleOp: + op.Respond(s.fs.ReleaseDirHandle(typed)) + + case *fuseops.OpenFileOp: + op.Respond(s.fs.OpenFile(typed)) + + case *fuseops.ReadFileOp: + op.Respond(s.fs.ReadFile(typed)) + + case *fuseops.WriteFileOp: + op.Respond(s.fs.WriteFile(typed)) + + case *fuseops.SyncFileOp: + op.Respond(s.fs.SyncFile(typed)) + + case *fuseops.FlushFileOp: + op.Respond(s.fs.FlushFile(typed)) + + case *fuseops.ReleaseFileHandleOp: + op.Respond(s.fs.ReleaseFileHandle(typed)) + } + } +}