Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go-fuse
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Levin Zimmermann
go-fuse
Commits
de39580d
Commit
de39580d
authored
Feb 24, 2019
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nodefs: rename Node to Operations
This should decrease confusion between Inode and Node
parent
74afa852
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
50 additions
and
48 deletions
+50
-48
nodefs/api.go
nodefs/api.go
+16
-13
nodefs/bridge.go
nodefs/bridge.go
+2
-3
nodefs/default.go
nodefs/default.go
+18
-18
nodefs/inode.go
nodefs/inode.go
+11
-11
nodefs/loopback.go
nodefs/loopback.go
+3
-3
No files found.
nodefs/api.go
View file @
de39580d
...
...
@@ -19,7 +19,7 @@
//
// A /-separated string path describes location of a node in the tree. For example
//
//
/
dir1/file
// dir1/file
//
// describes path root → dir1 → file.
//
...
...
@@ -28,13 +28,15 @@
// expressed through index-nodes (also known as "inode", see Inode) which
// describe parent/child relation in between nodes and node-ID association.
//
// A particular filesystem should provide nodes with filesystem operations
// implemented as defined by Node interface. When filesystem is mounted, its
// root Node is associated with root of the tree, and the tree is further build
// lazily when nodefs infrastructure needs to lookup children of nodes to
// process client requests. For every new node, the filesystem infrastructure
// automatically builds new index node and links it in the filesystem tree.
// InodeOf can be used to get particular Inode associated with a Node.
// A particular filesystem should provide nodes with filesystem
// operations implemented as defined by Operations interface. When
// filesystem is mounted, its root Operations is associated with root
// of the tree, and the tree is further build lazily when nodefs
// infrastructure needs to lookup children of nodes to process client
// requests. For every new Operations, the filesystem infrastructure
// 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).
//
...
...
@@ -57,7 +59,7 @@ import (
//
// The identity of the Inode does not change over the lifetime of
// the node object.
func
InodeOf
(
node
Node
)
*
Inode
{
func
InodeOf
(
node
Operations
)
*
Inode
{
return
node
.
inode
()
}
...
...
@@ -68,10 +70,11 @@ NOSUBMIT: how to structure?
- one interface for files (getattr, read/write), one for dirs (lookup, opendir), one shared?
- one giant interface?
- 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.
//
// When a new Node instance is created, e.g. on Lookup, it has nil Inode.
...
...
@@ -91,7 +94,7 @@ type Node interface {
Mknod
(
ctx
context
.
Context
,
name
string
,
mode
uint32
,
dev
uint32
,
out
*
fuse
.
EntryOut
)
(
*
Inode
,
fuse
.
Status
)
Rmdir
(
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
)
...
...
nodefs/bridge.go
View file @
de39580d
...
...
@@ -37,8 +37,7 @@ type rawBridge struct {
}
// newInode creates creates new inode pointing to node.
// XXX - should store the Ino number we expose in GetAttr too ?
func
(
b
*
rawBridge
)
newInode
(
node
Node
,
mode
uint32
,
id
FileID
,
persistent
bool
)
*
Inode
{
func
(
b
*
rawBridge
)
newInode
(
node
Operations
,
mode
uint32
,
id
FileID
,
persistent
bool
)
*
Inode
{
b
.
mu
.
Lock
()
defer
b
.
mu
.
Unlock
()
...
...
@@ -84,7 +83,7 @@ func (b *rawBridge) newInode(node Node, mode uint32, id FileID, persistent bool)
return
inode
}
func
NewNodeFS
(
root
Node
,
opts
*
Options
)
fuse
.
RawFileSystem
{
func
NewNodeFS
(
root
Operations
,
opts
*
Options
)
fuse
.
RawFileSystem
{
bridge
:=
&
rawBridge
{
RawFileSystem
:
fuse
.
NewDefaultRawFileSystem
(),
automaticIno
:
1
<<
63
,
...
...
nodefs/default.go
View file @
de39580d
...
...
@@ -11,36 +11,36 @@ import (
"github.com/hanwen/go-fuse/fuse"
)
// Default
Node
provides common base Node functionality.
// Default
Operations
provides common base Node functionality.
//
// It must be embedded in any Node implementation.
type
Default
Node
struct
{
type
Default
Operations
struct
{
inode_
*
Inode
}
func
(
dn
*
Default
Node
)
setInode
(
inode
*
Inode
)
{
func
(
dn
*
Default
Operations
)
setInode
(
inode
*
Inode
)
{
dn
.
inode_
=
inode
}
func
(
dn
*
Default
Node
)
inode
()
*
Inode
{
func
(
dn
*
Default
Operations
)
inode
()
*
Inode
{
return
dn
.
inode_
}
func
(
n
*
Default
Node
)
Read
(
ctx
context
.
Context
,
f
File
,
dest
[]
byte
,
off
int64
)
(
fuse
.
ReadResult
,
fuse
.
Status
)
{
func
(
n
*
Default
Operations
)
Read
(
ctx
context
.
Context
,
f
File
,
dest
[]
byte
,
off
int64
)
(
fuse
.
ReadResult
,
fuse
.
Status
)
{
if
f
!=
nil
{
return
f
.
Read
(
ctx
,
dest
,
off
)
}
return
nil
,
fuse
.
ENOSYS
}
func
(
n
*
Default
Node
)
Fsync
(
ctx
context
.
Context
,
f
File
,
flags
uint32
)
fuse
.
Status
{
func
(
n
*
Default
Operations
)
Fsync
(
ctx
context
.
Context
,
f
File
,
flags
uint32
)
fuse
.
Status
{
if
f
!=
nil
{
return
f
.
Fsync
(
ctx
,
flags
)
}
return
fuse
.
ENOSYS
}
func
(
n
*
Default
Node
)
Write
(
ctx
context
.
Context
,
f
File
,
data
[]
byte
,
off
int64
)
(
written
uint32
,
code
fuse
.
Status
)
{
func
(
n
*
Default
Operations
)
Write
(
ctx
context
.
Context
,
f
File
,
data
[]
byte
,
off
int64
)
(
written
uint32
,
code
fuse
.
Status
)
{
if
f
!=
nil
{
return
f
.
Write
(
ctx
,
data
,
off
)
}
...
...
@@ -48,7 +48,7 @@ func (n *DefaultNode) Write(ctx context.Context, f File, data []byte, off int64)
return
0
,
fuse
.
ENOSYS
}
func
(
n
*
Default
Node
)
GetLk
(
ctx
context
.
Context
,
f
File
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
,
out
*
fuse
.
FileLock
)
(
code
fuse
.
Status
)
{
func
(
n
*
Default
Operations
)
GetLk
(
ctx
context
.
Context
,
f
File
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
,
out
*
fuse
.
FileLock
)
(
code
fuse
.
Status
)
{
if
f
!=
nil
{
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.
return
fuse
.
ENOSYS
}
func
(
n
*
Default
Node
)
SetLk
(
ctx
context
.
Context
,
f
File
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
)
(
code
fuse
.
Status
)
{
func
(
n
*
Default
Operations
)
SetLk
(
ctx
context
.
Context
,
f
File
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
)
(
code
fuse
.
Status
)
{
if
f
!=
nil
{
return
f
.
SetLk
(
ctx
,
owner
,
lk
,
flags
)
}
...
...
@@ -64,14 +64,14 @@ func (n *DefaultNode) SetLk(ctx context.Context, f File, owner uint64, lk *fuse.
return
fuse
.
ENOSYS
}
func
(
n
*
Default
Node
)
SetLkw
(
ctx
context
.
Context
,
f
File
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
)
(
code
fuse
.
Status
)
{
func
(
n
*
Default
Operations
)
SetLkw
(
ctx
context
.
Context
,
f
File
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
)
(
code
fuse
.
Status
)
{
if
f
!=
nil
{
return
f
.
SetLkw
(
ctx
,
owner
,
lk
,
flags
)
}
return
fuse
.
ENOSYS
}
func
(
n
*
Default
Node
)
Flush
(
ctx
context
.
Context
,
f
File
)
fuse
.
Status
{
func
(
n
*
Default
Operations
)
Flush
(
ctx
context
.
Context
,
f
File
)
fuse
.
Status
{
if
f
!=
nil
{
return
f
.
Flush
(
ctx
)
}
...
...
@@ -79,13 +79,13 @@ func (n *DefaultNode) Flush(ctx context.Context, f File) fuse.Status {
return
fuse
.
ENOSYS
}
func
(
n
*
Default
Node
)
Release
(
ctx
context
.
Context
,
f
File
)
{
func
(
n
*
Default
Operations
)
Release
(
ctx
context
.
Context
,
f
File
)
{
if
f
!=
nil
{
f
.
Release
(
ctx
)
}
}
func
(
n
*
Default
Node
)
Allocate
(
ctx
context
.
Context
,
f
File
,
off
uint64
,
size
uint64
,
mode
uint32
)
(
code
fuse
.
Status
)
{
func
(
n
*
Default
Operations
)
Allocate
(
ctx
context
.
Context
,
f
File
,
off
uint64
,
size
uint64
,
mode
uint32
)
(
code
fuse
.
Status
)
{
if
f
!=
nil
{
return
f
.
Allocate
(
ctx
,
off
,
size
,
mode
)
}
...
...
@@ -93,7 +93,7 @@ func (n *DefaultNode) Allocate(ctx context.Context, f File, off uint64, size uin
return
fuse
.
ENOSYS
}
func
(
n
*
Default
Node
)
GetAttr
(
ctx
context
.
Context
,
f
File
,
out
*
fuse
.
AttrOut
)
fuse
.
Status
{
func
(
n
*
Default
Operations
)
GetAttr
(
ctx
context
.
Context
,
f
File
,
out
*
fuse
.
AttrOut
)
fuse
.
Status
{
if
f
!=
nil
{
f
.
GetAttr
(
ctx
,
out
)
}
...
...
@@ -101,7 +101,7 @@ func (n *DefaultNode) GetAttr(ctx context.Context, f File, out *fuse.AttrOut) fu
return
fuse
.
ENOSYS
}
func
(
n
*
Default
Node
)
Truncate
(
ctx
context
.
Context
,
f
File
,
size
uint64
)
fuse
.
Status
{
func
(
n
*
Default
Operations
)
Truncate
(
ctx
context
.
Context
,
f
File
,
size
uint64
)
fuse
.
Status
{
if
f
!=
nil
{
return
f
.
Truncate
(
ctx
,
size
)
}
...
...
@@ -109,7 +109,7 @@ func (n *DefaultNode) Truncate(ctx context.Context, f File, size uint64) fuse.St
return
fuse
.
ENOSYS
}
func
(
n
*
Default
Node
)
Chown
(
ctx
context
.
Context
,
f
File
,
uid
uint32
,
gid
uint32
)
fuse
.
Status
{
func
(
n
*
Default
Operations
)
Chown
(
ctx
context
.
Context
,
f
File
,
uid
uint32
,
gid
uint32
)
fuse
.
Status
{
if
f
!=
nil
{
return
f
.
Chown
(
ctx
,
uid
,
gid
)
}
...
...
@@ -117,7 +117,7 @@ func (n *DefaultNode) Chown(ctx context.Context, f File, uid uint32, gid uint32)
return
fuse
.
ENOSYS
}
func
(
n
*
Default
Node
)
Chmod
(
ctx
context
.
Context
,
f
File
,
perms
uint32
)
fuse
.
Status
{
func
(
n
*
Default
Operations
)
Chmod
(
ctx
context
.
Context
,
f
File
,
perms
uint32
)
fuse
.
Status
{
if
f
!=
nil
{
return
f
.
Chmod
(
ctx
,
perms
)
}
...
...
@@ -125,7 +125,7 @@ func (n *DefaultNode) Chmod(ctx context.Context, f File, perms uint32) fuse.Stat
return
fuse
.
ENOSYS
}
func
(
n
*
Default
Node
)
Utimens
(
ctx
context
.
Context
,
f
File
,
atime
*
time
.
Time
,
mtime
*
time
.
Time
)
fuse
.
Status
{
func
(
n
*
Default
Operations
)
Utimens
(
ctx
context
.
Context
,
f
File
,
atime
*
time
.
Time
,
mtime
*
time
.
Time
)
fuse
.
Status
{
if
f
!=
nil
{
return
f
.
Utimens
(
ctx
,
atime
,
mtime
)
}
...
...
nodefs/inode.go
View file @
de39580d
...
...
@@ -27,7 +27,7 @@ type FileID struct {
// objects in the file system. It is used to communicate to
// the kernel about this file object. The values uint64(-1),
// 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
// When reusing a previously used inode number for a new
...
...
@@ -42,17 +42,17 @@ func (i *FileID) Reserved() bool {
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
//
instances, which is the extension interface for file systems. On
e
//
can create fully-formed trees of Inodes ahead of time by creating
// "persistent" Inodes.
// Inode is a node in VFS tree. Inodes are one-to-one mapped to
//
Operations instances, which is the extension interface for fil
e
//
systems. One can create fully-formed trees of Inodes ahead of time
//
by creating
"persistent" Inodes.
type
Inode
struct
{
// The filetype bits from the mode.
mode
uint32
nodeID
FileID
node
Node
node
Operations
bridge
*
rawBridge
// Following data is mutable.
...
...
@@ -179,7 +179,7 @@ func (n *Inode) Forgotten() bool {
}
// Node returns the Node object implementing the file system operations.
func
(
n
*
Inode
)
Node
()
Node
{
func
(
n
*
Inode
)
Operations
()
Operations
{
return
n
.
node
}
...
...
@@ -255,7 +255,7 @@ func (iparent *Inode) setEntry(name string, ichild *Inode) {
// NewPersistentInode returns an Inode whose lifetime is not in
// 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
)
}
...
...
@@ -266,16 +266,16 @@ func (n *Inode) ForgetPersistent() {
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
// 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
// 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
)
}
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
)
}
...
...
nodefs/loopback.go
View file @
de39580d
...
...
@@ -39,7 +39,7 @@ func (n *loopbackRoot) GetAttr(ctx context.Context, f File, out *fuse.AttrOut) f
}
type
loopbackNode
struct
{
Default
Node
Default
Operations
rootNode
*
loopbackRoot
...
...
@@ -130,7 +130,7 @@ func (n *loopbackNode) Unlink(ctx context.Context, name string) fuse.Status {
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
{
return
fuse
.
ENOSYS
...
...
@@ -227,7 +227,7 @@ func (n *loopbackNode) GetAttr(ctx context.Context, f File, out *fuse.AttrOut) f
return
fuse
.
OK
}
func
NewLoopback
(
root
string
)
Node
{
func
NewLoopback
(
root
string
)
Operations
{
n
:=
&
loopbackRoot
{
root
:
root
,
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment