Commit fed41d2f authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

nodefs: split out Operations interface in single-method interfaces

This is the prevalent style for FUSE libraries in Go.
parent cc423d1b
This diff is collapsed.
This diff is collapsed.
...@@ -19,7 +19,7 @@ import ( ...@@ -19,7 +19,7 @@ import (
) )
type keepCacheFile struct { type keepCacheFile struct {
OperationStubs InodeEmbed
keepCache bool keepCache bool
mu sync.Mutex mu sync.Mutex
...@@ -61,12 +61,18 @@ func (f *keepCacheFile) Read(ctx context.Context, fh FileHandle, dest []byte, of ...@@ -61,12 +61,18 @@ func (f *keepCacheFile) Read(ctx context.Context, fh FileHandle, dest []byte, of
return fuse.ReadResultData(f.content[off:]), OK return fuse.ReadResultData(f.content[off:]), OK
} }
var _ = (Reader)((*keepCacheFile)(nil))
var _ = (Opener)((*keepCacheFile)(nil))
var _ = (Getattrer)((*keepCacheFile)(nil))
type keepCacheRoot struct { type keepCacheRoot struct {
OperationStubs InodeEmbed
keep, nokeep *keepCacheFile keep, nokeep *keepCacheFile
} }
var _ = (OnAdder)((*keepCacheRoot)(nil))
func (r *keepCacheRoot) OnAdd(ctx context.Context) { func (r *keepCacheRoot) OnAdd(ctx context.Context) {
i := r.Inode() i := r.Inode()
......
This diff is collapsed.
...@@ -17,7 +17,7 @@ import ( ...@@ -17,7 +17,7 @@ import (
) )
type dioRoot struct { type dioRoot struct {
OperationStubs InodeEmbed
} }
func (r *dioRoot) OnAdd(ctx context.Context) { func (r *dioRoot) OnAdd(ctx context.Context) {
...@@ -27,9 +27,11 @@ func (r *dioRoot) OnAdd(ctx context.Context) { ...@@ -27,9 +27,11 @@ func (r *dioRoot) OnAdd(ctx context.Context) {
// A file handle that pretends that every hole/data starts at // A file handle that pretends that every hole/data starts at
// multiples of 1024 // multiples of 1024
type dioFH struct { type dioFH struct {
FileHandleStubs
} }
var _ = (FileLseeker)((*dioFH)(nil))
var _ = (FileReader)((*dioFH)(nil))
func (f *dioFH) Lseek(ctx context.Context, off uint64, whence uint32) (uint64, syscall.Errno) { func (f *dioFH) Lseek(ctx context.Context, off uint64, whence uint32) (uint64, syscall.Errno) {
next := (off + 1023) & (^uint64(1023)) next := (off + 1023) & (^uint64(1023))
return next, OK return next, OK
...@@ -42,9 +44,11 @@ func (fh *dioFH) Read(ctx context.Context, data []byte, off int64) (fuse.ReadRes ...@@ -42,9 +44,11 @@ func (fh *dioFH) Read(ctx context.Context, data []byte, off int64) (fuse.ReadRes
// overrides Open so it can return a dioFH file handle // overrides Open so it can return a dioFH file handle
type dioFile struct { type dioFile struct {
OperationStubs InodeEmbed
} }
var _ = (Opener)((*dioFile)(nil))
func (f *dioFile) Open(ctx context.Context, flags uint32) (fh FileHandle, fuseFlags uint32, errno syscall.Errno) { func (f *dioFile) Open(ctx context.Context, flags uint32) (fh FileHandle, fuseFlags uint32, errno syscall.Errno) {
return &dioFH{}, fuse.FOPEN_DIRECT_IO, OK return &dioFH{}, fuse.FOPEN_DIRECT_IO, OK
} }
......
...@@ -24,6 +24,20 @@ type loopbackFile struct { ...@@ -24,6 +24,20 @@ type loopbackFile struct {
fd int fd int
} }
var _ = (FileHandle)((*loopbackFile)(nil))
var _ = (FileReleaser)((*loopbackFile)(nil))
var _ = (FileGetattrer)((*loopbackFile)(nil))
var _ = (FileReader)((*loopbackFile)(nil))
var _ = (FileWriter)((*loopbackFile)(nil))
var _ = (FileGetlker)((*loopbackFile)(nil))
var _ = (FileSetlker)((*loopbackFile)(nil))
var _ = (FileSetlkwer)((*loopbackFile)(nil))
var _ = (FileLseeker)((*loopbackFile)(nil))
var _ = (FileFlusher)((*loopbackFile)(nil))
var _ = (FileFsyncer)((*loopbackFile)(nil))
var _ = (FileSetattrer)((*loopbackFile)(nil))
var _ = (FileAllocater)((*loopbackFile)(nil))
func (f *loopbackFile) Read(ctx context.Context, buf []byte, off int64) (res fuse.ReadResult, errno syscall.Errno) { func (f *loopbackFile) Read(ctx context.Context, buf []byte, off int64) (res fuse.ReadResult, errno syscall.Errno) {
r := fuse.ReadResultFd(uintptr(f.fd), off, len(buf)) r := fuse.ReadResultFd(uintptr(f.fd), off, len(buf))
return r, OK return r, OK
......
...@@ -53,7 +53,7 @@ func (i *NodeAttr) Reserved() bool { ...@@ -53,7 +53,7 @@ func (i *NodeAttr) Reserved() bool {
type Inode struct { type Inode struct {
nodeAttr NodeAttr nodeAttr NodeAttr
ops Operations ops InodeLink
bridge *rawBridge bridge *rawBridge
// Following data is mutable. // Following data is mutable.
...@@ -90,18 +90,6 @@ type Inode struct { ...@@ -90,18 +90,6 @@ type Inode struct {
parents map[parentData]struct{} parents map[parentData]struct{}
} }
func (n *Inode) dirOps() DirOperations {
return n.ops.(DirOperations)
}
func (n *Inode) fileOps() FileOperations {
return n.ops.(FileOperations)
}
func (n *Inode) linkOps() SymlinkOperations {
return n.ops.(SymlinkOperations)
}
// NodeAttr returns the (Ino, Gen) tuple for this node. // NodeAttr returns the (Ino, Gen) tuple for this node.
func (n *Inode) NodeAttr() NodeAttr { func (n *Inode) NodeAttr() NodeAttr {
return n.nodeAttr return n.nodeAttr
...@@ -214,7 +202,7 @@ func (n *Inode) Forgotten() bool { ...@@ -214,7 +202,7 @@ func (n *Inode) Forgotten() bool {
// Operations returns the object implementing the file system // Operations returns the object implementing the file system
// operations. // operations.
func (n *Inode) Operations() Operations { func (n *Inode) Operations() InodeLink {
return n.ops return n.ops
} }
...@@ -273,7 +261,7 @@ func (iparent *Inode) setEntry(name string, ichild *Inode) { ...@@ -273,7 +261,7 @@ func (iparent *Inode) setEntry(name string, ichild *Inode) {
// NewPersistentInode returns an Inode whose lifetime is not in // NewPersistentInode returns an Inode whose lifetime is not in
// control of the kernel. // control of the kernel.
func (n *Inode) NewPersistentInode(ctx context.Context, node Operations, id NodeAttr) *Inode { func (n *Inode) NewPersistentInode(ctx context.Context, node InodeLink, id NodeAttr) *Inode {
return n.newInode(ctx, node, id, true) return n.newInode(ctx, node, id, true)
} }
...@@ -284,16 +272,16 @@ func (n *Inode) ForgetPersistent() { ...@@ -284,16 +272,16 @@ func (n *Inode) ForgetPersistent() {
n.removeRef(0, true) n.removeRef(0, true)
} }
// NewInode returns an inode for the given Operations. The mode should // NewInode returns an inode for the given InodeLink. The mode should
// be standard mode argument (eg. S_IFDIR). The inode number in id.Ino // be standard mode argument (eg. S_IFDIR). The inode number in id.Ino
// argument is used to implement hard-links. If it is given, and // argument is used to implement hard-links. If it is given, and
// another node with the same ID is known, that will node will be // another node with the same ID is known, that will node will be
// returned, and the passed-in `node` is ignored. // returned, and the passed-in `node` is ignored.
func (n *Inode) NewInode(ctx context.Context, ops Operations, id NodeAttr) *Inode { func (n *Inode) NewInode(ctx context.Context, ops InodeLink, id NodeAttr) *Inode {
return n.newInode(ctx, ops, id, false) return n.newInode(ctx, ops, id, false)
} }
func (n *Inode) newInode(ctx context.Context, ops Operations, id NodeAttr, persistent bool) *Inode { func (n *Inode) newInode(ctx context.Context, ops InodeLink, id NodeAttr, persistent bool) *Inode {
return n.bridge.newInode(ctx, ops, id, persistent) return n.bridge.newInode(ctx, ops, id, persistent)
} }
......
...@@ -17,14 +17,11 @@ import ( ...@@ -17,14 +17,11 @@ import (
) )
type interruptRoot struct { type interruptRoot struct {
OperationStubs InodeEmbed
child interruptOps child interruptOps
} }
type interruptOps struct { var _ = (Lookuper)((*interruptRoot)(nil))
OperationStubs
interrupted bool
}
func (r *interruptRoot) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*Inode, syscall.Errno) { func (r *interruptRoot) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*Inode, syscall.Errno) {
if name != "file" { if name != "file" {
...@@ -37,6 +34,13 @@ func (r *interruptRoot) Lookup(ctx context.Context, name string, out *fuse.Entry ...@@ -37,6 +34,13 @@ func (r *interruptRoot) Lookup(ctx context.Context, name string, out *fuse.Entry
return ch, OK return ch, OK
} }
type interruptOps struct {
InodeEmbed
interrupted bool
}
var _ = (Opener)((*interruptOps)(nil))
func (o *interruptOps) Open(ctx context.Context, flags uint32) (FileHandle, uint32, syscall.Errno) { func (o *interruptOps) Open(ctx context.Context, flags uint32) (FileHandle, uint32, syscall.Errno) {
select { select {
case <-time.After(100 * time.Millisecond): case <-time.After(100 * time.Millisecond):
......
...@@ -6,7 +6,6 @@ package nodefs ...@@ -6,7 +6,6 @@ package nodefs
import ( import (
"context" "context"
"log"
"os" "os"
"path/filepath" "path/filepath"
"syscall" "syscall"
...@@ -21,6 +20,27 @@ type loopbackRoot struct { ...@@ -21,6 +20,27 @@ type loopbackRoot struct {
rootDev uint64 rootDev uint64
} }
var _ = (Statfser)((*loopbackNode)(nil))
var _ = (Getattrer)((*loopbackNode)(nil))
var _ = (Getxattrer)((*loopbackNode)(nil))
var _ = (Setxattrer)((*loopbackNode)(nil))
var _ = (Removexattrer)((*loopbackNode)(nil))
var _ = (Listxattrer)((*loopbackNode)(nil))
var _ = (Readlinker)((*loopbackNode)(nil))
var _ = (Opener)((*loopbackNode)(nil))
var _ = (CopyFileRanger)((*loopbackNode)(nil))
var _ = (Lookuper)((*loopbackNode)(nil))
var _ = (Opendirer)((*loopbackNode)(nil))
var _ = (Readdirer)((*loopbackNode)(nil))
var _ = (Mkdirer)((*loopbackNode)(nil))
var _ = (Mknoder)((*loopbackNode)(nil))
var _ = (Linker)((*loopbackNode)(nil))
var _ = (Symlinker)((*loopbackNode)(nil))
var _ = (Creater)((*loopbackNode)(nil))
var _ = (Unlinker)((*loopbackNode)(nil))
var _ = (Rmdirer)((*loopbackNode)(nil))
var _ = (Renamer)((*loopbackNode)(nil))
func (n *loopbackNode) Statfs(ctx context.Context, out *fuse.StatfsOut) syscall.Errno { func (n *loopbackNode) Statfs(ctx context.Context, out *fuse.StatfsOut) syscall.Errno {
s := syscall.Statfs_t{} s := syscall.Statfs_t{}
err := syscall.Statfs(n.path(), &s) err := syscall.Statfs(n.path(), &s)
...@@ -32,7 +52,6 @@ func (n *loopbackNode) Statfs(ctx context.Context, out *fuse.StatfsOut) syscall. ...@@ -32,7 +52,6 @@ func (n *loopbackNode) Statfs(ctx context.Context, out *fuse.StatfsOut) syscall.
} }
func (n *loopbackRoot) Getattr(ctx context.Context, out *fuse.AttrOut) syscall.Errno { func (n *loopbackRoot) Getattr(ctx context.Context, out *fuse.AttrOut) syscall.Errno {
log.Println("getattr")
st := syscall.Stat_t{} st := syscall.Stat_t{}
err := syscall.Stat(n.rootPath, &st) err := syscall.Stat(n.rootPath, &st)
if err != nil { if err != nil {
...@@ -43,7 +62,7 @@ func (n *loopbackRoot) Getattr(ctx context.Context, out *fuse.AttrOut) syscall.E ...@@ -43,7 +62,7 @@ func (n *loopbackRoot) Getattr(ctx context.Context, out *fuse.AttrOut) syscall.E
} }
type loopbackNode struct { type loopbackNode struct {
OperationStubs InodeEmbed
} }
func (n *loopbackNode) root() *loopbackRoot { func (n *loopbackNode) root() *loopbackRoot {
...@@ -122,14 +141,14 @@ func (n *loopbackNode) Unlink(ctx context.Context, name string) syscall.Errno { ...@@ -122,14 +141,14 @@ func (n *loopbackNode) Unlink(ctx context.Context, name string) syscall.Errno {
return ToErrno(err) return ToErrno(err)
} }
func toLoopbackNode(op Operations) *loopbackNode { func toLoopbackNode(op InodeLink) *loopbackNode {
if r, ok := op.(*loopbackRoot); ok { if r, ok := op.(*loopbackRoot); ok {
return &r.loopbackNode return &r.loopbackNode
} }
return op.(*loopbackNode) return op.(*loopbackNode)
} }
func (n *loopbackNode) Rename(ctx context.Context, name string, newParent Operations, newName string, flags uint32) syscall.Errno { func (n *loopbackNode) Rename(ctx context.Context, name string, newParent InodeLink, newName string, flags uint32) syscall.Errno {
newParentLoopback := toLoopbackNode(newParent) newParentLoopback := toLoopbackNode(newParent)
if flags&RENAME_EXCHANGE != 0 { if flags&RENAME_EXCHANGE != 0 {
return n.renameExchange(name, newParentLoopback, newName) return n.renameExchange(name, newParentLoopback, newName)
...@@ -199,7 +218,7 @@ func (n *loopbackNode) Symlink(ctx context.Context, target, name string, out *fu ...@@ -199,7 +218,7 @@ func (n *loopbackNode) Symlink(ctx context.Context, target, name string, out *fu
return ch, 0 return ch, 0
} }
func (n *loopbackNode) Link(ctx context.Context, target Operations, name string, out *fuse.EntryOut) (*Inode, syscall.Errno) { func (n *loopbackNode) Link(ctx context.Context, target InodeLink, name string, out *fuse.EntryOut) (*Inode, syscall.Errno) {
p := filepath.Join(n.path(), name) p := filepath.Join(n.path(), name)
targetNode := toLoopbackNode(target) targetNode := toLoopbackNode(target)
...@@ -258,11 +277,7 @@ func (n *loopbackNode) Readdir(ctx context.Context) (DirStream, syscall.Errno) { ...@@ -258,11 +277,7 @@ func (n *loopbackNode) Readdir(ctx context.Context) (DirStream, syscall.Errno) {
return NewLoopbackDirStream(n.path()) return NewLoopbackDirStream(n.path())
} }
func (n *loopbackNode) Fgetattr(ctx context.Context, f FileHandle, out *fuse.AttrOut) syscall.Errno { func (n *loopbackNode) Getattr(ctx context.Context, out *fuse.AttrOut) syscall.Errno {
if f != nil {
return f.Getattr(ctx, out)
}
p := n.path() p := n.path()
var err error = nil var err error = nil
...@@ -277,7 +292,7 @@ func (n *loopbackNode) Fgetattr(ctx context.Context, f FileHandle, out *fuse.Att ...@@ -277,7 +292,7 @@ func (n *loopbackNode) Fgetattr(ctx context.Context, f FileHandle, out *fuse.Att
// NewLoopback returns a root node for a loopback file system whose // NewLoopback returns a root node for a loopback file system whose
// root is at the given root. // root is at the given root.
func NewLoopbackRoot(root string) (DirOperations, error) { func NewLoopbackRoot(root string) (InodeLink, error) {
var st syscall.Stat_t var st syscall.Stat_t
err := syscall.Stat(root, &st) err := syscall.Stat(root, &st)
if err != nil { if err != nil {
......
...@@ -14,7 +14,7 @@ import ( ...@@ -14,7 +14,7 @@ import (
// requests. This is a convenience wrapper around NewNodeFS and // requests. This is a convenience wrapper around NewNodeFS and
// fuse.NewServer. If nil is given as options, default settings are // fuse.NewServer. If nil is given as options, default settings are
// applied, which are 1 second entry and attribute timeout. // applied, which are 1 second entry and attribute timeout.
func Mount(dir string, root DirOperations, options *Options) (*fuse.Server, error) { func Mount(dir string, root InodeLink, options *Options) (*fuse.Server, error) {
if options == nil { if options == nil {
oneSec := time.Second oneSec := time.Second
options = &Options{ options = &Options{
......
...@@ -28,7 +28,7 @@ type testCase struct { ...@@ -28,7 +28,7 @@ type testCase struct {
origDir string origDir string
mntDir string mntDir string
loopback DirOperations loopback InodeLink
rawFS fuse.RawFileSystem rawFS fuse.RawFileSystem
server *fuse.Server server *fuse.Server
} }
......
...@@ -106,14 +106,15 @@ func TestZipFS(t *testing.T) { ...@@ -106,14 +106,15 @@ func TestZipFS(t *testing.T) {
// zipFile is a file read from a zip archive. // zipFile is a file read from a zip archive.
type zipFile struct { type zipFile struct {
OperationStubs InodeEmbed
file *zip.File file *zip.File
mu sync.Mutex mu sync.Mutex
data []byte data []byte
} }
var _ = (FileOperations)((*zipFile)(nil)) var _ = (Opener)((*zipFile)(nil))
var _ = (Getattrer)((*zipFile)(nil))
// Getattr sets the minimum, which is the size. A more full-featured // Getattr sets the minimum, which is the size. A more full-featured
// FS would also set timestamps and permissions. // FS would also set timestamps and permissions.
...@@ -157,11 +158,13 @@ func (zf *zipFile) Read(ctx context.Context, f FileHandle, dest []byte, off int6 ...@@ -157,11 +158,13 @@ func (zf *zipFile) Read(ctx context.Context, f FileHandle, dest []byte, off int6
// zipRoot is the root of the Zip filesystem. Its only functionality // zipRoot is the root of the Zip filesystem. Its only functionality
// is populating the filesystem. // is populating the filesystem.
type zipRoot struct { type zipRoot struct {
OperationStubs InodeEmbed
r *zip.Reader r *zip.Reader
} }
var _ = (OnAdder)((*zipRoot)(nil))
func (zr *zipRoot) OnAdd(ctx context.Context) { func (zr *zipRoot) OnAdd(ctx context.Context) {
// OnAdd is called once we are attached to an Inode. We can // OnAdd is called once we are attached to an Inode. We can
// then construct a tree. We construct the entire tree, and // then construct a tree. We construct the entire tree, and
...@@ -177,7 +180,7 @@ func (zr *zipRoot) OnAdd(ctx context.Context) { ...@@ -177,7 +180,7 @@ func (zr *zipRoot) OnAdd(ctx context.Context) {
} }
ch := p.GetChild(component) ch := p.GetChild(component)
if ch == nil { if ch == nil {
ch = p.NewPersistentInode(ctx, &OperationStubs{}, ch = p.NewPersistentInode(ctx, &InodeEmbed{},
NodeAttr{Mode: fuse.S_IFDIR}) NodeAttr{Mode: fuse.S_IFDIR})
p.AddChild(component, ch, true) p.AddChild(component, ch, true)
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment