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

nodefs: rename Node to Operations

This should decrease confusion between Inode and Node
parent 74afa852
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
// //
// A /-separated string path describes location of a node in the tree. For example // A /-separated string path describes location of a node in the tree. For example
// //
// /dir1/file // dir1/file
// //
// describes path root → dir1 → file. // describes path root → dir1 → file.
// //
...@@ -28,13 +28,15 @@ ...@@ -28,13 +28,15 @@
// expressed through index-nodes (also known as "inode", see Inode) which // expressed through index-nodes (also known as "inode", see Inode) which
// describe parent/child relation in between nodes and node-ID association. // describe parent/child relation in between nodes and node-ID association.
// //
// A particular filesystem should provide nodes with filesystem operations // A particular filesystem should provide nodes with filesystem
// implemented as defined by Node interface. When filesystem is mounted, its // operations implemented as defined by Operations interface. When
// root Node is associated with root of the tree, and the tree is further build // filesystem is mounted, its root Operations is associated with root
// lazily when nodefs infrastructure needs to lookup children of nodes to // of the tree, and the tree is further build lazily when nodefs
// process client requests. For every new node, the filesystem infrastructure // infrastructure needs to lookup children of nodes to process client
// automatically builds new index node and links it in the filesystem tree. // requests. For every new Operations, the filesystem infrastructure
// InodeOf can be used to get particular Inode associated with a Node. // automatically builds new index node and links it in the filesystem
// tree. InodeOf can be used to get particular Inode associated with
// a Operations.
// //
// XXX ^^^ inodes cleaned on cache clean (FORGET). // XXX ^^^ inodes cleaned on cache clean (FORGET).
// //
...@@ -57,7 +59,7 @@ import ( ...@@ -57,7 +59,7 @@ import (
// //
// The identity of the Inode does not change over the lifetime of // The identity of the Inode does not change over the lifetime of
// the node object. // the node object.
func InodeOf(node Node) *Inode { func InodeOf(node Operations) *Inode {
return node.inode() return node.inode()
} }
...@@ -68,10 +70,11 @@ NOSUBMIT: how to structure? ...@@ -68,10 +70,11 @@ NOSUBMIT: how to structure?
- one interface for files (getattr, read/write), one for dirs (lookup, opendir), one shared? - one interface for files (getattr, read/write), one for dirs (lookup, opendir), one shared?
- one giant interface? - one giant interface?
- use raw types as args rather than mimicking Golang signatures? - use raw types as args rather than mimicking Golang signatures?
Every Node implementation must directly or indirectly embed DefaultNode.
*/ */
type Node interface {
// Operations is the interface that implements the filesystem. Each
// Operations instance must embed DefaultNode.
type Operations interface {
// setInode and inode are used by nodefs internally to link Inode to a Node. // setInode and inode are used by nodefs internally to link Inode to a Node.
// //
// When a new Node instance is created, e.g. on Lookup, it has nil Inode. // When a new Node instance is created, e.g. on Lookup, it has nil Inode.
...@@ -91,7 +94,7 @@ type Node interface { ...@@ -91,7 +94,7 @@ type Node interface {
Mknod(ctx context.Context, name string, mode uint32, dev uint32, out *fuse.EntryOut) (*Inode, fuse.Status) Mknod(ctx context.Context, name string, mode uint32, dev uint32, out *fuse.EntryOut) (*Inode, fuse.Status)
Rmdir(ctx context.Context, name string) fuse.Status Rmdir(ctx context.Context, name string) fuse.Status
Unlink(ctx context.Context, name string) fuse.Status Unlink(ctx context.Context, name string) fuse.Status
Rename(ctx context.Context, name string, newParent Node, newName string, flags uint32) fuse.Status Rename(ctx context.Context, name string, newParent Operations, newName string, flags uint32) fuse.Status
Open(ctx context.Context, flags uint32) (fh File, fuseFlags uint32, code fuse.Status) Open(ctx context.Context, flags uint32) (fh File, fuseFlags uint32, code fuse.Status)
......
...@@ -37,8 +37,7 @@ type rawBridge struct { ...@@ -37,8 +37,7 @@ type rawBridge struct {
} }
// newInode creates creates new inode pointing to node. // newInode creates creates new inode pointing to node.
// XXX - should store the Ino number we expose in GetAttr too ? func (b *rawBridge) newInode(node Operations, mode uint32, id FileID, persistent bool) *Inode {
func (b *rawBridge) newInode(node Node, mode uint32, id FileID, persistent bool) *Inode {
b.mu.Lock() b.mu.Lock()
defer b.mu.Unlock() defer b.mu.Unlock()
...@@ -84,7 +83,7 @@ func (b *rawBridge) newInode(node Node, mode uint32, id FileID, persistent bool) ...@@ -84,7 +83,7 @@ func (b *rawBridge) newInode(node Node, mode uint32, id FileID, persistent bool)
return inode return inode
} }
func NewNodeFS(root Node, opts *Options) fuse.RawFileSystem { func NewNodeFS(root Operations, opts *Options) fuse.RawFileSystem {
bridge := &rawBridge{ bridge := &rawBridge{
RawFileSystem: fuse.NewDefaultRawFileSystem(), RawFileSystem: fuse.NewDefaultRawFileSystem(),
automaticIno: 1 << 63, automaticIno: 1 << 63,
......
...@@ -11,36 +11,36 @@ import ( ...@@ -11,36 +11,36 @@ import (
"github.com/hanwen/go-fuse/fuse" "github.com/hanwen/go-fuse/fuse"
) )
// DefaultNode provides common base Node functionality. // DefaultOperations provides common base Node functionality.
// //
// It must be embedded in any Node implementation. // It must be embedded in any Node implementation.
type DefaultNode struct { type DefaultOperations struct {
inode_ *Inode inode_ *Inode
} }
func (dn *DefaultNode) setInode(inode *Inode) { func (dn *DefaultOperations) setInode(inode *Inode) {
dn.inode_ = inode dn.inode_ = inode
} }
func (dn *DefaultNode) inode() *Inode { func (dn *DefaultOperations) inode() *Inode {
return dn.inode_ return dn.inode_
} }
func (n *DefaultNode) Read(ctx context.Context, f File, dest []byte, off int64) (fuse.ReadResult, fuse.Status) { func (n *DefaultOperations) Read(ctx context.Context, f File, dest []byte, off int64) (fuse.ReadResult, fuse.Status) {
if f != nil { if f != nil {
return f.Read(ctx, dest, off) return f.Read(ctx, dest, off)
} }
return nil, fuse.ENOSYS return nil, fuse.ENOSYS
} }
func (n *DefaultNode) Fsync(ctx context.Context, f File, flags uint32) fuse.Status { func (n *DefaultOperations) Fsync(ctx context.Context, f File, flags uint32) fuse.Status {
if f != nil { if f != nil {
return f.Fsync(ctx, flags) return f.Fsync(ctx, flags)
} }
return fuse.ENOSYS return fuse.ENOSYS
} }
func (n *DefaultNode) Write(ctx context.Context, f File, data []byte, off int64) (written uint32, code fuse.Status) { func (n *DefaultOperations) Write(ctx context.Context, f File, data []byte, off int64) (written uint32, code fuse.Status) {
if f != nil { if f != nil {
return f.Write(ctx, data, off) return f.Write(ctx, data, off)
} }
...@@ -48,7 +48,7 @@ func (n *DefaultNode) Write(ctx context.Context, f File, data []byte, off int64) ...@@ -48,7 +48,7 @@ func (n *DefaultNode) Write(ctx context.Context, f File, data []byte, off int64)
return 0, fuse.ENOSYS return 0, fuse.ENOSYS
} }
func (n *DefaultNode) GetLk(ctx context.Context, f File, owner uint64, lk *fuse.FileLock, flags uint32, out *fuse.FileLock) (code fuse.Status) { func (n *DefaultOperations) GetLk(ctx context.Context, f File, owner uint64, lk *fuse.FileLock, flags uint32, out *fuse.FileLock) (code fuse.Status) {
if f != nil { if f != nil {
return f.GetLk(ctx, owner, lk, flags, out) return f.GetLk(ctx, owner, lk, flags, out)
} }
...@@ -56,7 +56,7 @@ func (n *DefaultNode) GetLk(ctx context.Context, f File, owner uint64, lk *fuse. ...@@ -56,7 +56,7 @@ func (n *DefaultNode) GetLk(ctx context.Context, f File, owner uint64, lk *fuse.
return fuse.ENOSYS return fuse.ENOSYS
} }
func (n *DefaultNode) SetLk(ctx context.Context, f File, owner uint64, lk *fuse.FileLock, flags uint32) (code fuse.Status) { func (n *DefaultOperations) SetLk(ctx context.Context, f File, owner uint64, lk *fuse.FileLock, flags uint32) (code fuse.Status) {
if f != nil { if f != nil {
return f.SetLk(ctx, owner, lk, flags) return f.SetLk(ctx, owner, lk, flags)
} }
...@@ -64,14 +64,14 @@ func (n *DefaultNode) SetLk(ctx context.Context, f File, owner uint64, lk *fuse. ...@@ -64,14 +64,14 @@ func (n *DefaultNode) SetLk(ctx context.Context, f File, owner uint64, lk *fuse.
return fuse.ENOSYS return fuse.ENOSYS
} }
func (n *DefaultNode) SetLkw(ctx context.Context, f File, owner uint64, lk *fuse.FileLock, flags uint32) (code fuse.Status) { func (n *DefaultOperations) SetLkw(ctx context.Context, f File, owner uint64, lk *fuse.FileLock, flags uint32) (code fuse.Status) {
if f != nil { if f != nil {
return f.SetLkw(ctx, owner, lk, flags) return f.SetLkw(ctx, owner, lk, flags)
} }
return fuse.ENOSYS return fuse.ENOSYS
} }
func (n *DefaultNode) Flush(ctx context.Context, f File) fuse.Status { func (n *DefaultOperations) Flush(ctx context.Context, f File) fuse.Status {
if f != nil { if f != nil {
return f.Flush(ctx) return f.Flush(ctx)
} }
...@@ -79,13 +79,13 @@ func (n *DefaultNode) Flush(ctx context.Context, f File) fuse.Status { ...@@ -79,13 +79,13 @@ func (n *DefaultNode) Flush(ctx context.Context, f File) fuse.Status {
return fuse.ENOSYS return fuse.ENOSYS
} }
func (n *DefaultNode) Release(ctx context.Context, f File) { func (n *DefaultOperations) Release(ctx context.Context, f File) {
if f != nil { if f != nil {
f.Release(ctx) f.Release(ctx)
} }
} }
func (n *DefaultNode) Allocate(ctx context.Context, f File, off uint64, size uint64, mode uint32) (code fuse.Status) { func (n *DefaultOperations) Allocate(ctx context.Context, f File, off uint64, size uint64, mode uint32) (code fuse.Status) {
if f != nil { if f != nil {
return f.Allocate(ctx, off, size, mode) return f.Allocate(ctx, off, size, mode)
} }
...@@ -93,7 +93,7 @@ func (n *DefaultNode) Allocate(ctx context.Context, f File, off uint64, size uin ...@@ -93,7 +93,7 @@ func (n *DefaultNode) Allocate(ctx context.Context, f File, off uint64, size uin
return fuse.ENOSYS return fuse.ENOSYS
} }
func (n *DefaultNode) GetAttr(ctx context.Context, f File, out *fuse.AttrOut) fuse.Status { func (n *DefaultOperations) GetAttr(ctx context.Context, f File, out *fuse.AttrOut) fuse.Status {
if f != nil { if f != nil {
f.GetAttr(ctx, out) f.GetAttr(ctx, out)
} }
...@@ -101,7 +101,7 @@ func (n *DefaultNode) GetAttr(ctx context.Context, f File, out *fuse.AttrOut) fu ...@@ -101,7 +101,7 @@ func (n *DefaultNode) GetAttr(ctx context.Context, f File, out *fuse.AttrOut) fu
return fuse.ENOSYS return fuse.ENOSYS
} }
func (n *DefaultNode) Truncate(ctx context.Context, f File, size uint64) fuse.Status { func (n *DefaultOperations) Truncate(ctx context.Context, f File, size uint64) fuse.Status {
if f != nil { if f != nil {
return f.Truncate(ctx, size) return f.Truncate(ctx, size)
} }
...@@ -109,7 +109,7 @@ func (n *DefaultNode) Truncate(ctx context.Context, f File, size uint64) fuse.St ...@@ -109,7 +109,7 @@ func (n *DefaultNode) Truncate(ctx context.Context, f File, size uint64) fuse.St
return fuse.ENOSYS return fuse.ENOSYS
} }
func (n *DefaultNode) Chown(ctx context.Context, f File, uid uint32, gid uint32) fuse.Status { func (n *DefaultOperations) Chown(ctx context.Context, f File, uid uint32, gid uint32) fuse.Status {
if f != nil { if f != nil {
return f.Chown(ctx, uid, gid) return f.Chown(ctx, uid, gid)
} }
...@@ -117,7 +117,7 @@ func (n *DefaultNode) Chown(ctx context.Context, f File, uid uint32, gid uint32) ...@@ -117,7 +117,7 @@ func (n *DefaultNode) Chown(ctx context.Context, f File, uid uint32, gid uint32)
return fuse.ENOSYS return fuse.ENOSYS
} }
func (n *DefaultNode) Chmod(ctx context.Context, f File, perms uint32) fuse.Status { func (n *DefaultOperations) Chmod(ctx context.Context, f File, perms uint32) fuse.Status {
if f != nil { if f != nil {
return f.Chmod(ctx, perms) return f.Chmod(ctx, perms)
} }
...@@ -125,7 +125,7 @@ func (n *DefaultNode) Chmod(ctx context.Context, f File, perms uint32) fuse.Stat ...@@ -125,7 +125,7 @@ func (n *DefaultNode) Chmod(ctx context.Context, f File, perms uint32) fuse.Stat
return fuse.ENOSYS return fuse.ENOSYS
} }
func (n *DefaultNode) Utimens(ctx context.Context, f File, atime *time.Time, mtime *time.Time) fuse.Status { func (n *DefaultOperations) Utimens(ctx context.Context, f File, atime *time.Time, mtime *time.Time) fuse.Status {
if f != nil { if f != nil {
return f.Utimens(ctx, atime, mtime) return f.Utimens(ctx, atime, mtime)
} }
......
...@@ -27,7 +27,7 @@ type FileID struct { ...@@ -27,7 +27,7 @@ type FileID struct {
// objects in the file system. It is used to communicate to // objects in the file system. It is used to communicate to
// the kernel about this file object. The values uint64(-1), // the kernel about this file object. The values uint64(-1),
// and 1 are reserved. When using Ino==0, a unique, sequential // and 1 are reserved. When using Ino==0, a unique, sequential
// number is assigned (starting at 2^63) // number is assigned (starting at 2^63) on Inode creation.
Ino uint64 Ino uint64
// When reusing a previously used inode number for a new // When reusing a previously used inode number for a new
...@@ -42,17 +42,17 @@ func (i *FileID) Reserved() bool { ...@@ -42,17 +42,17 @@ func (i *FileID) Reserved() bool {
return i.Ino == 0 || i.Ino == 1 || i.Ino == ^uint64(0) return i.Ino == 0 || i.Ino == 1 || i.Ino == ^uint64(0)
} }
// Inode is a node in VFS tree. Inodes are one-to-one mapped to Node // Inode is a node in VFS tree. Inodes are one-to-one mapped to
// instances, which is the extension interface for file systems. One // Operations instances, which is the extension interface for file
// can create fully-formed trees of Inodes ahead of time by creating // systems. One can create fully-formed trees of Inodes ahead of time
// "persistent" Inodes. // by creating "persistent" Inodes.
type Inode struct { type Inode struct {
// The filetype bits from the mode. // The filetype bits from the mode.
mode uint32 mode uint32
nodeID FileID nodeID FileID
node Node node Operations
bridge *rawBridge bridge *rawBridge
// Following data is mutable. // Following data is mutable.
...@@ -179,7 +179,7 @@ func (n *Inode) Forgotten() bool { ...@@ -179,7 +179,7 @@ func (n *Inode) Forgotten() bool {
} }
// Node returns the Node object implementing the file system operations. // Node returns the Node object implementing the file system operations.
func (n *Inode) Node() Node { func (n *Inode) Operations() Operations {
return n.node return n.node
} }
...@@ -255,7 +255,7 @@ func (iparent *Inode) setEntry(name string, ichild *Inode) { ...@@ -255,7 +255,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(node Node, mode uint32, opaque FileID) *Inode { func (n *Inode) NewPersistentInode(node Operations, mode uint32, opaque FileID) *Inode {
return n.newInode(node, mode, opaque, true) return n.newInode(node, mode, opaque, true)
} }
...@@ -266,16 +266,16 @@ func (n *Inode) ForgetPersistent() { ...@@ -266,16 +266,16 @@ func (n *Inode) ForgetPersistent() {
n.removeRef(0, true) n.removeRef(0, true)
} }
// NewInode returns an inode for the given Node. The mode should be // NewInode returns an inode for the given Operations. The mode should be
// standard mode argument (eg. S_IFDIR). The opaqueID argument, if // standard mode argument (eg. S_IFDIR). The opaqueID argument, if
// non-zero, is used to implement hard-links. If opaqueID is given, // non-zero, is used to implement hard-links. If opaqueID is given,
// and another node with the same ID is known, that will node will be // and 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(node Node, mode uint32, opaqueID FileID) *Inode { func (n *Inode) NewInode(node Operations, mode uint32, opaqueID FileID) *Inode {
return n.newInode(node, mode, opaqueID, false) return n.newInode(node, mode, opaqueID, false)
} }
func (n *Inode) newInode(node Node, mode uint32, opaqueID FileID, persistent bool) *Inode { func (n *Inode) newInode(node Operations, mode uint32, opaqueID FileID, persistent bool) *Inode {
return n.bridge.newInode(node, mode, opaqueID, persistent) return n.bridge.newInode(node, mode, opaqueID, persistent)
} }
......
...@@ -39,7 +39,7 @@ func (n *loopbackRoot) GetAttr(ctx context.Context, f File, out *fuse.AttrOut) f ...@@ -39,7 +39,7 @@ func (n *loopbackRoot) GetAttr(ctx context.Context, f File, out *fuse.AttrOut) f
} }
type loopbackNode struct { type loopbackNode struct {
DefaultNode DefaultOperations
rootNode *loopbackRoot rootNode *loopbackRoot
...@@ -130,7 +130,7 @@ func (n *loopbackNode) Unlink(ctx context.Context, name string) fuse.Status { ...@@ -130,7 +130,7 @@ func (n *loopbackNode) Unlink(ctx context.Context, name string) fuse.Status {
return fuse.ToStatus(err) return fuse.ToStatus(err)
} }
func (n *loopbackNode) Rename(ctx context.Context, name string, newParent Node, newName string, flags uint32) fuse.Status { func (n *loopbackNode) Rename(ctx context.Context, name string, newParent Operations, newName string, flags uint32) fuse.Status {
if flags != 0 { if flags != 0 {
return fuse.ENOSYS return fuse.ENOSYS
...@@ -227,7 +227,7 @@ func (n *loopbackNode) GetAttr(ctx context.Context, f File, out *fuse.AttrOut) f ...@@ -227,7 +227,7 @@ func (n *loopbackNode) GetAttr(ctx context.Context, f File, out *fuse.AttrOut) f
return fuse.OK return fuse.OK
} }
func NewLoopback(root string) Node { func NewLoopback(root string) Operations {
n := &loopbackRoot{ n := &loopbackRoot{
root: root, root: root,
} }
......
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