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
2f9c4b1d
Commit
2f9c4b1d
authored
Mar 15, 2019
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nodefs: split up interface futher
* MutableDirOperations * XAttrOperations * LockOperations
parent
17f8f123
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
217 additions
and
161 deletions
+217
-161
nodefs/api.go
nodefs/api.go
+58
-47
nodefs/bridge.go
nodefs/bridge.go
+132
-73
nodefs/default.go
nodefs/default.go
+25
-41
nodefs/simple_test.go
nodefs/simple_test.go
+2
-0
No files found.
nodefs/api.go
View file @
2f9c4b1d
...
...
@@ -67,22 +67,6 @@ func InodeOf(node Operations) *Inode {
return
node
.
inode
()
}
// DirStream lists directory entries.
type
DirStream
interface
{
// HasNext indicates if there are further entries. HasNext
// might be called on already closed streams.
HasNext
()
bool
// Next retrieves the next entry. It is only called if HasNext
// has previously returned true. The Status may be used to
// indicate I/O errors
Next
()
(
fuse
.
DirEntry
,
fuse
.
Status
)
// Close releases resources related to this directory
// stream.
Close
()
}
// Operations is the interface that implements the filesystem. Each
// Operations instance must embed DefaultNode.
type
Operations
interface
{
...
...
@@ -106,7 +90,16 @@ type Operations interface {
// susan gets the UID and GID for susan here.
Access
(
ctx
context
.
Context
,
mask
uint32
)
fuse
.
Status
// Extended attributes
// GetAttr reads attributes for an Inode
GetAttr
(
ctx
context
.
Context
,
out
*
fuse
.
AttrOut
)
fuse
.
Status
// SetAttr sets attributes for an Inode.
SetAttr
(
ctx
context
.
Context
,
in
*
fuse
.
SetAttrIn
,
out
*
fuse
.
AttrOut
)
fuse
.
Status
}
// XAttrOperations is as collection of methods used to implement extended attributes.
type
XAttrOperations
interface
{
Operations
// GetXAttr should read data for the given attribute into
// `dest` and return the number of bytes. If `dest` is too
...
...
@@ -124,12 +117,6 @@ type Operations interface {
// `dest`. If the `dest` buffer is too small, it should return
// ERANGE and the correct size.
ListXAttr
(
ctx
context
.
Context
,
dest
[]
byte
)
(
uint32
,
fuse
.
Status
)
// GetAttr reads attributes for an Inode
GetAttr
(
ctx
context
.
Context
,
out
*
fuse
.
AttrOut
)
fuse
.
Status
// SetAttr sets attributes for an Inode
SetAttr
(
ctx
context
.
Context
,
in
*
fuse
.
SetAttrIn
,
out
*
fuse
.
AttrOut
)
fuse
.
Status
}
// SymlinkOperations holds operations specific to symlinks.
...
...
@@ -143,8 +130,6 @@ type SymlinkOperations interface {
// FileOperations holds operations that apply to regular files. The
// default implementation, as returned from NewFileOperations forwards
// to the passed-in FileHandle.
//
// XXX Mknod output too?
type
FileOperations
interface
{
Operations
...
...
@@ -154,19 +139,6 @@ type FileOperations interface {
// File locking
// GetLk returns locks that would conflict with the given
// input lock. If no locks conflict, the output has type
// L_UNLCK. See fcntl(2) for more information.
GetLk
(
ctx
context
.
Context
,
f
FileHandle
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
,
out
*
fuse
.
FileLock
)
(
status
fuse
.
Status
)
// Obtain a lock on a file, or fail if the lock could not
// obtained. See fcntl(2) for more information.
SetLk
(
ctx
context
.
Context
,
f
FileHandle
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
)
(
status
fuse
.
Status
)
// Obtain a lock on a file, waiting if necessary. See fcntl(2)
// for more information.
SetLkw
(
ctx
context
.
Context
,
f
FileHandle
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
)
(
status
fuse
.
Status
)
// Reads data from a file. The data should be returned as
// ReadResult, which may be constructed from the incoming
// `dest` buffer. If the file was opened without FileHandle,
...
...
@@ -206,6 +178,40 @@ type FileOperations interface {
FSetAttr
(
ctx
context
.
Context
,
f
FileHandle
,
in
*
fuse
.
SetAttrIn
,
out
*
fuse
.
AttrOut
)
fuse
.
Status
}
// LockOperations are operations for locking regions of regular files.
type
LockOperations
interface
{
FileOperations
// GetLk returns locks that would conflict with the given
// input lock. If no locks conflict, the output has type
// L_UNLCK. See fcntl(2) for more information.
GetLk
(
ctx
context
.
Context
,
f
FileHandle
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
,
out
*
fuse
.
FileLock
)
(
status
fuse
.
Status
)
// Obtain a lock on a file, or fail if the lock could not
// obtained. See fcntl(2) for more information.
SetLk
(
ctx
context
.
Context
,
f
FileHandle
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
)
(
status
fuse
.
Status
)
// Obtain a lock on a file, waiting if necessary. See fcntl(2)
// for more information.
SetLkw
(
ctx
context
.
Context
,
f
FileHandle
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
)
(
status
fuse
.
Status
)
}
// DirStream lists directory entries.
type
DirStream
interface
{
// HasNext indicates if there are further entries. HasNext
// might be called on already closed streams.
HasNext
()
bool
// Next retrieves the next entry. It is only called if HasNext
// has previously returned true. The Status may be used to
// indicate I/O errors
Next
()
(
fuse
.
DirEntry
,
fuse
.
Status
)
// Close releases resources related to this directory
// stream.
Close
()
}
// DirOperations are operations for directory nodes in the filesystem.
type
DirOperations
interface
{
Operations
...
...
@@ -219,6 +225,20 @@ type DirOperations interface {
// tree automatically if the return status is OK.
Lookup
(
ctx
context
.
Context
,
name
string
,
out
*
fuse
.
EntryOut
)
(
*
Inode
,
fuse
.
Status
)
// OpenDir opens a directory Inode for reading its
// contents. The actual reading is driven from ReadDir, so
// this method is just for performing sanity/permission
// checks.
OpenDir
(
ctx
context
.
Context
)
fuse
.
Status
// ReadDir opens a stream of directory entries.
ReadDir
(
ctx
context
.
Context
)
(
DirStream
,
fuse
.
Status
)
}
// MutableDirOperations are operations that change the hierarchy of a file system.
type
MutableDirOperations
interface
{
DirOperations
// Mkdir is similar to Lookup, but must create a directory entry and Inode.
Mkdir
(
ctx
context
.
Context
,
name
string
,
mode
uint32
,
out
*
fuse
.
EntryOut
)
(
*
Inode
,
fuse
.
Status
)
...
...
@@ -248,15 +268,6 @@ type DirOperations interface {
// different one. The changes is effected in the FS tree if
// the return status is OK
Rename
(
ctx
context
.
Context
,
name
string
,
newParent
Operations
,
newName
string
,
flags
uint32
)
fuse
.
Status
// OpenDir opens a directory Inode for reading its
// contents. The actual reading is driven from ReadDir, so
// this method is just for performing sanity/permission
// checks.
OpenDir
(
ctx
context
.
Context
)
fuse
.
Status
// ReadDir opens a stream of directory entries.
ReadDir
(
ctx
context
.
Context
)
(
DirStream
,
fuse
.
Status
)
}
// FileHandle is a resource identifier for opened files. For a
...
...
nodefs/bridge.go
View file @
2f9c4b1d
...
...
@@ -101,6 +101,43 @@ func (b *rawBridge) newInode(ops Operations, mode uint32, id FileID, persistent
return
ops
.
inode
()
}
// addNewChild inserts the child into the tree. Returns file handle if file != nil.
func
(
b
*
rawBridge
)
addNewChild
(
parent
*
Inode
,
name
string
,
child
*
Inode
,
file
FileHandle
,
fileFlags
uint32
,
out
*
fuse
.
EntryOut
)
uint32
{
lockNodes
(
parent
,
child
)
parent
.
setEntry
(
name
,
child
)
b
.
mu
.
Lock
()
child
.
lookupCount
++
var
fh
uint32
if
file
!=
nil
{
fh
=
b
.
registerFile
(
child
,
file
,
fileFlags
)
}
out
.
NodeId
=
child
.
nodeID
.
Ino
out
.
Generation
=
child
.
nodeID
.
Gen
out
.
Attr
.
Ino
=
child
.
nodeID
.
Ino
b
.
mu
.
Unlock
()
unlockNodes
(
parent
,
child
)
return
fh
}
func
(
b
*
rawBridge
)
setEntryOutTimeout
(
out
*
fuse
.
EntryOut
)
{
if
b
.
options
.
AttrTimeout
!=
nil
{
out
.
SetAttrTimeout
(
*
b
.
options
.
AttrTimeout
)
}
if
b
.
options
.
EntryTimeout
!=
nil
{
out
.
SetEntryTimeout
(
*
b
.
options
.
EntryTimeout
)
}
}
func
(
b
*
rawBridge
)
setAttrTimeout
(
out
*
fuse
.
AttrOut
)
{
if
b
.
options
.
AttrTimeout
!=
nil
{
out
.
SetTimeout
(
*
b
.
options
.
AttrTimeout
)
}
}
// NewNodeFS creates a node based filesystem based on an Operations
// instance for the root.
func
NewNodeFS
(
root
DirOperations
,
opts
*
Options
)
fuse
.
RawFileSystem
{
...
...
@@ -169,7 +206,11 @@ func (b *rawBridge) Lookup(cancel <-chan struct{}, header *fuse.InHeader, name s
func
(
b
*
rawBridge
)
Rmdir
(
cancel
<-
chan
struct
{},
header
*
fuse
.
InHeader
,
name
string
)
fuse
.
Status
{
parent
,
_
:=
b
.
inode
(
header
.
NodeId
,
0
)
status
:=
parent
.
dirOps
()
.
Rmdir
(
&
fuse
.
Context
{
Caller
:
header
.
Caller
,
Cancel
:
cancel
},
name
)
var
status
fuse
.
Status
if
mops
,
ok
:=
parent
.
ops
.
(
MutableDirOperations
);
ok
{
status
=
mops
.
Rmdir
(
&
fuse
.
Context
{
Caller
:
header
.
Caller
,
Cancel
:
cancel
},
name
)
}
if
status
.
Ok
()
{
parent
.
RmChild
(
name
)
}
...
...
@@ -179,17 +220,26 @@ func (b *rawBridge) Rmdir(cancel <-chan struct{}, header *fuse.InHeader, name st
func
(
b
*
rawBridge
)
Unlink
(
cancel
<-
chan
struct
{},
header
*
fuse
.
InHeader
,
name
string
)
fuse
.
Status
{
parent
,
_
:=
b
.
inode
(
header
.
NodeId
,
0
)
status
:=
parent
.
dirOps
()
.
Unlink
(
&
fuse
.
Context
{
Caller
:
header
.
Caller
,
Cancel
:
cancel
},
name
)
var
status
fuse
.
Status
if
mops
,
ok
:=
parent
.
ops
.
(
MutableDirOperations
);
ok
{
status
=
mops
.
Unlink
(
&
fuse
.
Context
{
Caller
:
header
.
Caller
,
Cancel
:
cancel
},
name
)
}
if
status
.
Ok
()
{
parent
.
RmChild
(
name
)
}
return
status
}
func
(
b
*
rawBridge
)
Mkdir
(
cancel
<-
chan
struct
{},
input
*
fuse
.
MkdirIn
,
name
string
,
out
*
fuse
.
EntryOut
)
(
status
fuse
.
Status
)
{
func
(
b
*
rawBridge
)
Mkdir
(
cancel
<-
chan
struct
{},
input
*
fuse
.
MkdirIn
,
name
string
,
out
*
fuse
.
EntryOut
)
fuse
.
Status
{
parent
,
_
:=
b
.
inode
(
input
.
NodeId
,
0
)
child
,
status
:=
parent
.
dirOps
()
.
Mkdir
(
&
fuse
.
Context
{
Caller
:
input
.
Caller
,
Cancel
:
cancel
},
name
,
input
.
Mode
,
out
)
var
child
*
Inode
var
status
fuse
.
Status
if
mops
,
ok
:=
parent
.
ops
.
(
MutableDirOperations
);
ok
{
child
,
status
=
mops
.
Mkdir
(
&
fuse
.
Context
{
Caller
:
input
.
Caller
,
Cancel
:
cancel
},
name
,
input
.
Mode
,
out
)
}
if
!
status
.
Ok
()
{
return
status
}
...
...
@@ -203,10 +253,15 @@ func (b *rawBridge) Mkdir(cancel <-chan struct{}, input *fuse.MkdirIn, name stri
return
fuse
.
OK
}
func
(
b
*
rawBridge
)
Mknod
(
cancel
<-
chan
struct
{},
input
*
fuse
.
MknodIn
,
name
string
,
out
*
fuse
.
EntryOut
)
(
status
fuse
.
Status
)
{
func
(
b
*
rawBridge
)
Mknod
(
cancel
<-
chan
struct
{},
input
*
fuse
.
MknodIn
,
name
string
,
out
*
fuse
.
EntryOut
)
fuse
.
Status
{
parent
,
_
:=
b
.
inode
(
input
.
NodeId
,
0
)
child
,
status
:=
parent
.
dirOps
()
.
Mknod
(
&
fuse
.
Context
{
Caller
:
input
.
Caller
,
Cancel
:
cancel
},
name
,
input
.
Mode
,
input
.
Rdev
,
out
)
var
child
*
Inode
var
status
fuse
.
Status
if
mops
,
ok
:=
parent
.
ops
.
(
MutableDirOperations
);
ok
{
child
,
status
=
mops
.
Mknod
(
&
fuse
.
Context
{
Caller
:
input
.
Caller
,
Cancel
:
cancel
},
name
,
input
.
Mode
,
input
.
Rdev
,
out
)
}
if
!
status
.
Ok
()
{
return
status
}
...
...
@@ -216,41 +271,18 @@ func (b *rawBridge) Mknod(cancel <-chan struct{}, input *fuse.MknodIn, name stri
return
fuse
.
OK
}
// addNewChild inserts the child into the tree. Returns file handle if file != nil.
func
(
b
*
rawBridge
)
addNewChild
(
parent
*
Inode
,
name
string
,
child
*
Inode
,
file
FileHandle
,
fileFlags
uint32
,
out
*
fuse
.
EntryOut
)
uint32
{
lockNodes
(
parent
,
child
)
parent
.
setEntry
(
name
,
child
)
b
.
mu
.
Lock
()
child
.
lookupCount
++
var
fh
uint32
if
file
!=
nil
{
fh
=
b
.
registerFile
(
child
,
file
,
fileFlags
)
}
out
.
NodeId
=
child
.
nodeID
.
Ino
out
.
Generation
=
child
.
nodeID
.
Gen
out
.
Attr
.
Ino
=
child
.
nodeID
.
Ino
b
.
mu
.
Unlock
()
unlockNodes
(
parent
,
child
)
return
fh
}
func
(
b
*
rawBridge
)
Create
(
cancel
<-
chan
struct
{},
input
*
fuse
.
CreateIn
,
name
string
,
out
*
fuse
.
CreateOut
)
fuse
.
Status
{
ctx
:=
&
fuse
.
Context
{
Caller
:
input
.
Caller
,
Cancel
:
cancel
}
parent
,
_
:=
b
.
inode
(
input
.
NodeId
,
0
)
func
(
b
*
rawBridge
)
setEntryOutTimeout
(
out
*
fuse
.
EntryOut
)
{
if
b
.
options
.
AttrTimeout
!=
nil
{
out
.
SetAttrTimeout
(
*
b
.
options
.
AttrTimeout
)
var
child
*
Inode
var
status
fuse
.
Status
var
f
FileHandle
var
flags
uint32
if
mops
,
ok
:=
parent
.
ops
.
(
MutableDirOperations
);
ok
{
child
,
f
,
flags
,
status
=
mops
.
Create
(
ctx
,
name
,
input
.
Flags
,
input
.
Mode
)
}
if
b
.
options
.
EntryTimeout
!=
nil
{
out
.
SetEntryTimeout
(
*
b
.
options
.
EntryTimeout
)
}
}
func
(
b
*
rawBridge
)
Create
(
cancel
<-
chan
struct
{},
input
*
fuse
.
CreateIn
,
name
string
,
out
*
fuse
.
CreateOut
)
(
status
fuse
.
Status
)
{
ctx
:=
&
fuse
.
Context
{
Caller
:
input
.
Caller
,
Cancel
:
cancel
}
parent
,
_
:=
b
.
inode
(
input
.
NodeId
,
0
)
child
,
f
,
flags
,
status
:=
parent
.
dirOps
()
.
Create
(
ctx
,
name
,
input
.
Flags
,
input
.
Mode
)
if
!
status
.
Ok
()
{
if
b
.
options
.
NegativeTimeout
!=
nil
{
out
.
SetEntryTimeout
(
*
b
.
options
.
NegativeTimeout
)
...
...
@@ -313,12 +345,6 @@ func (b *rawBridge) GetAttr(cancel <-chan struct{}, input *fuse.GetAttrIn, out *
return
n
.
ops
.
GetAttr
(
ctx
,
out
)
}
func
(
b
*
rawBridge
)
setAttrTimeout
(
out
*
fuse
.
AttrOut
)
{
if
b
.
options
.
AttrTimeout
!=
nil
{
out
.
SetTimeout
(
*
b
.
options
.
AttrTimeout
)
}
}
func
(
b
*
rawBridge
)
SetAttr
(
cancel
<-
chan
struct
{},
in
*
fuse
.
SetAttrIn
,
out
*
fuse
.
AttrOut
)
(
status
fuse
.
Status
)
{
ctx
:=
&
fuse
.
Context
{
Caller
:
in
.
Caller
,
Cancel
:
cancel
}
...
...
@@ -339,41 +365,52 @@ func (b *rawBridge) Rename(cancel <-chan struct{}, input *fuse.RenameIn, oldName
p1
,
_
:=
b
.
inode
(
input
.
NodeId
,
0
)
p2
,
_
:=
b
.
inode
(
input
.
Newdir
,
0
)
status
:=
p1
.
dirOps
()
.
Rename
(
&
fuse
.
Context
{
Caller
:
input
.
Caller
,
Cancel
:
cancel
},
oldName
,
p2
.
ops
,
newName
,
input
.
Flags
)
if
status
.
Ok
()
{
if
input
.
Flags
&
unix
.
RENAME_EXCHANGE
!=
0
{
p1
.
ExchangeChild
(
oldName
,
p2
,
newName
)
}
else
{
p1
.
MvChild
(
oldName
,
p2
,
newName
,
true
)
if
mops
,
ok
:=
p1
.
ops
.
(
MutableDirOperations
);
ok
{
status
:=
mops
.
Rename
(
&
fuse
.
Context
{
Caller
:
input
.
Caller
,
Cancel
:
cancel
},
oldName
,
p2
.
ops
,
newName
,
input
.
Flags
)
if
status
.
Ok
()
{
if
input
.
Flags
&
unix
.
RENAME_EXCHANGE
!=
0
{
p1
.
ExchangeChild
(
oldName
,
p2
,
newName
)
}
else
{
p1
.
MvChild
(
oldName
,
p2
,
newName
,
true
)
}
return
status
}
}
return
status
return
fuse
.
ENOSYS
}
func
(
b
*
rawBridge
)
Link
(
cancel
<-
chan
struct
{},
input
*
fuse
.
LinkIn
,
name
string
,
out
*
fuse
.
EntryOut
)
(
status
fuse
.
Status
)
{
parent
,
_
:=
b
.
inode
(
input
.
NodeId
,
0
)
target
,
_
:=
b
.
inode
(
input
.
Oldnodeid
,
0
)
child
,
status
:=
parent
.
dirOps
()
.
Link
(
&
fuse
.
Context
{
Caller
:
input
.
Caller
,
Cancel
:
cancel
},
target
.
ops
,
name
,
out
)
if
!
status
.
Ok
()
{
return
status
}
if
mops
,
ok
:=
parent
.
ops
.
(
MutableDirOperations
);
ok
{
child
,
status
:=
mops
.
Link
(
&
fuse
.
Context
{
Caller
:
input
.
Caller
,
Cancel
:
cancel
},
target
.
ops
,
name
,
out
)
if
!
status
.
Ok
()
{
return
status
}
b
.
addNewChild
(
parent
,
name
,
child
,
nil
,
0
,
out
)
b
.
setEntryOutTimeout
(
out
)
return
fuse
.
OK
b
.
addNewChild
(
parent
,
name
,
child
,
nil
,
0
,
out
)
b
.
setEntryOutTimeout
(
out
)
return
fuse
.
OK
}
return
fuse
.
ENOSYS
}
func
(
b
*
rawBridge
)
Symlink
(
cancel
<-
chan
struct
{},
header
*
fuse
.
InHeader
,
target
string
,
name
string
,
out
*
fuse
.
EntryOut
)
(
status
fuse
.
Status
)
{
parent
,
_
:=
b
.
inode
(
header
.
NodeId
,
0
)
child
,
status
:=
parent
.
dirOps
()
.
Symlink
(
&
fuse
.
Context
{
Caller
:
header
.
Caller
,
Cancel
:
cancel
},
target
,
name
,
out
)
if
!
status
.
Ok
()
{
return
status
}
b
.
addNewChild
(
parent
,
name
,
child
,
nil
,
0
,
out
)
b
.
setEntryOutTimeout
(
out
)
return
fuse
.
OK
if
mops
,
ok
:=
parent
.
ops
.
(
MutableDirOperations
);
ok
{
child
,
status
:=
mops
.
Symlink
(
&
fuse
.
Context
{
Caller
:
header
.
Caller
,
Cancel
:
cancel
},
target
,
name
,
out
)
if
!
status
.
Ok
()
{
return
status
}
b
.
addNewChild
(
parent
,
name
,
child
,
nil
,
0
,
out
)
b
.
setEntryOutTimeout
(
out
)
return
fuse
.
OK
}
return
fuse
.
ENOSYS
}
func
(
b
*
rawBridge
)
Readlink
(
cancel
<-
chan
struct
{},
header
*
fuse
.
InHeader
)
(
out
[]
byte
,
status
fuse
.
Status
)
{
...
...
@@ -396,22 +433,35 @@ func (b *rawBridge) Access(cancel <-chan struct{}, input *fuse.AccessIn) (status
func
(
b
*
rawBridge
)
GetXAttr
(
cancel
<-
chan
struct
{},
header
*
fuse
.
InHeader
,
attr
string
,
data
[]
byte
)
(
uint32
,
fuse
.
Status
)
{
n
,
_
:=
b
.
inode
(
header
.
NodeId
,
0
)
return
n
.
ops
.
GetXAttr
(
&
fuse
.
Context
{
Caller
:
header
.
Caller
,
Cancel
:
cancel
},
attr
,
data
)
if
xops
,
ok
:=
n
.
ops
.
(
XAttrOperations
);
ok
{
return
xops
.
GetXAttr
(
&
fuse
.
Context
{
Caller
:
header
.
Caller
,
Cancel
:
cancel
},
attr
,
data
)
}
return
0
,
fuse
.
ENOSYS
}
func
(
b
*
rawBridge
)
ListXAttr
(
cancel
<-
chan
struct
{},
header
*
fuse
.
InHeader
,
dest
[]
byte
)
(
sz
uint32
,
status
fuse
.
Status
)
{
n
,
_
:=
b
.
inode
(
header
.
NodeId
,
0
)
return
n
.
ops
.
ListXAttr
(
&
fuse
.
Context
{
Caller
:
header
.
Caller
,
Cancel
:
cancel
},
dest
)
if
xops
,
ok
:=
n
.
ops
.
(
XAttrOperations
);
ok
{
return
xops
.
ListXAttr
(
&
fuse
.
Context
{
Caller
:
header
.
Caller
,
Cancel
:
cancel
},
dest
)
}
return
0
,
fuse
.
ENOSYS
}
func
(
b
*
rawBridge
)
SetXAttr
(
cancel
<-
chan
struct
{},
input
*
fuse
.
SetXAttrIn
,
attr
string
,
data
[]
byte
)
fuse
.
Status
{
n
,
_
:=
b
.
inode
(
input
.
NodeId
,
0
)
return
n
.
ops
.
SetXAttr
(
&
fuse
.
Context
{
Caller
:
input
.
Caller
,
Cancel
:
cancel
},
attr
,
data
,
input
.
Flags
)
if
xops
,
ok
:=
n
.
ops
.
(
XAttrOperations
);
ok
{
return
xops
.
SetXAttr
(
&
fuse
.
Context
{
Caller
:
input
.
Caller
,
Cancel
:
cancel
},
attr
,
data
,
input
.
Flags
)
}
return
fuse
.
ENOSYS
}
func
(
b
*
rawBridge
)
RemoveXAttr
(
cancel
<-
chan
struct
{},
header
*
fuse
.
InHeader
,
attr
string
)
(
status
fuse
.
Status
)
{
n
,
_
:=
b
.
inode
(
header
.
NodeId
,
0
)
return
n
.
ops
.
RemoveXAttr
(
&
fuse
.
Context
{
Caller
:
header
.
Caller
,
Cancel
:
cancel
},
attr
)
if
xops
,
ok
:=
n
.
ops
.
(
XAttrOperations
);
ok
{
return
xops
.
RemoveXAttr
(
&
fuse
.
Context
{
Caller
:
header
.
Caller
,
Cancel
:
cancel
},
attr
)
}
return
fuse
.
ENOSYS
}
func
(
b
*
rawBridge
)
Open
(
cancel
<-
chan
struct
{},
input
*
fuse
.
OpenIn
,
out
*
fuse
.
OpenOut
)
(
status
fuse
.
Status
)
{
...
...
@@ -456,17 +506,26 @@ func (b *rawBridge) Read(cancel <-chan struct{}, input *fuse.ReadIn, buf []byte)
func
(
b
*
rawBridge
)
GetLk
(
cancel
<-
chan
struct
{},
input
*
fuse
.
LkIn
,
out
*
fuse
.
LkOut
)
(
status
fuse
.
Status
)
{
n
,
f
:=
b
.
inode
(
input
.
NodeId
,
input
.
Fh
)
return
n
.
fileOps
()
.
GetLk
(
&
fuse
.
Context
{
Caller
:
input
.
Caller
,
Cancel
:
cancel
},
f
.
file
,
input
.
Owner
,
&
input
.
Lk
,
input
.
LkFlags
,
&
out
.
Lk
)
if
lops
,
ok
:=
n
.
ops
.
(
LockOperations
);
ok
{
return
lops
.
GetLk
(
&
fuse
.
Context
{
Caller
:
input
.
Caller
,
Cancel
:
cancel
},
f
.
file
,
input
.
Owner
,
&
input
.
Lk
,
input
.
LkFlags
,
&
out
.
Lk
)
}
return
fuse
.
ENOSYS
}
func
(
b
*
rawBridge
)
SetLk
(
cancel
<-
chan
struct
{},
input
*
fuse
.
LkIn
)
(
status
fuse
.
Status
)
{
n
,
f
:=
b
.
inode
(
input
.
NodeId
,
input
.
Fh
)
return
n
.
fileOps
()
.
SetLk
(
&
fuse
.
Context
{
Caller
:
input
.
Caller
,
Cancel
:
cancel
},
f
.
file
,
input
.
Owner
,
&
input
.
Lk
,
input
.
LkFlags
)
if
lops
,
ok
:=
n
.
ops
.
(
LockOperations
);
ok
{
return
lops
.
SetLk
(
&
fuse
.
Context
{
Caller
:
input
.
Caller
,
Cancel
:
cancel
},
f
.
file
,
input
.
Owner
,
&
input
.
Lk
,
input
.
LkFlags
)
}
return
fuse
.
ENOSYS
}
func
(
b
*
rawBridge
)
SetLkw
(
cancel
<-
chan
struct
{},
input
*
fuse
.
LkIn
)
(
status
fuse
.
Status
)
{
n
,
f
:=
b
.
inode
(
input
.
NodeId
,
input
.
Fh
)
return
n
.
fileOps
()
.
SetLkw
(
&
fuse
.
Context
{
Caller
:
input
.
Caller
,
Cancel
:
cancel
},
f
.
file
,
input
.
Owner
,
&
input
.
Lk
,
input
.
LkFlags
)
if
lops
,
ok
:=
n
.
ops
.
(
LockOperations
);
ok
{
return
lops
.
SetLkw
(
&
fuse
.
Context
{
Caller
:
input
.
Caller
,
Cancel
:
cancel
},
f
.
file
,
input
.
Owner
,
&
input
.
Lk
,
input
.
LkFlags
)
}
return
fuse
.
ENOSYS
}
func
(
b
*
rawBridge
)
Release
(
input
*
fuse
.
ReleaseIn
)
{
...
...
nodefs/default.go
View file @
2f9c4b1d
...
...
@@ -8,7 +8,6 @@ import (
"context"
"log"
"sync/atomic"
"time"
"unsafe"
"github.com/hanwen/go-fuse/fuse"
...
...
@@ -47,15 +46,37 @@ func (n *DefaultOperations) setInode(inode *Inode) bool {
nil
,
unsafe
.
Pointer
(
inode
))
}
func
(
n
*
DefaultOperations
)
inode
()
*
Inode
{
return
(
*
Inode
)(
atomic
.
LoadPointer
(
(
*
unsafe
.
Pointer
)(
unsafe
.
Pointer
(
&
n
.
inode_
))))
}
func
(
n
*
DefaultOperations
)
StatFs
(
ctx
context
.
Context
,
out
*
fuse
.
StatfsOut
)
fuse
.
Status
{
// this should be defined on OSX, or the FS won't mount
*
out
=
fuse
.
StatfsOut
{}
return
fuse
.
OK
}
func
(
n
*
DefaultOperations
)
inode
()
*
Inode
{
return
(
*
Inode
)(
atomic
.
LoadPointer
(
(
*
unsafe
.
Pointer
)(
unsafe
.
Pointer
(
&
n
.
inode_
))))
func
(
n
*
DefaultOperations
)
GetAttr
(
ctx
context
.
Context
,
out
*
fuse
.
AttrOut
)
fuse
.
Status
{
return
fuse
.
ENOSYS
}
func
(
n
*
DefaultOperations
)
SetAttr
(
ctx
context
.
Context
,
in
*
fuse
.
SetAttrIn
,
out
*
fuse
.
AttrOut
)
fuse
.
Status
{
return
fuse
.
ENOSYS
}
func
(
n
*
DefaultOperations
)
Access
(
ctx
context
.
Context
,
mask
uint32
)
fuse
.
Status
{
return
fuse
.
ENOSYS
}
// ****************************************************************
func
(
n
*
DefaultOperations
)
FSetAttr
(
ctx
context
.
Context
,
f
FileHandle
,
in
*
fuse
.
SetAttrIn
,
out
*
fuse
.
AttrOut
)
fuse
.
Status
{
if
f
!=
nil
{
return
f
.
SetAttr
(
ctx
,
in
,
out
)
}
return
fuse
.
ENOSYS
}
func
(
n
*
DefaultOperations
)
Lookup
(
ctx
context
.
Context
,
name
string
,
out
*
fuse
.
EntryOut
)
(
*
Inode
,
fuse
.
Status
)
{
...
...
@@ -165,10 +186,6 @@ func (n *DefaultOperations) Allocate(ctx context.Context, f FileHandle, off uint
return
fuse
.
ENOSYS
}
func
(
n
*
DefaultOperations
)
GetAttr
(
ctx
context
.
Context
,
out
*
fuse
.
AttrOut
)
fuse
.
Status
{
return
fuse
.
ENOSYS
}
func
(
n
*
DefaultOperations
)
FGetAttr
(
ctx
context
.
Context
,
f
FileHandle
,
out
*
fuse
.
AttrOut
)
fuse
.
Status
{
if
f
!=
nil
{
f
.
GetAttr
(
ctx
,
out
)
...
...
@@ -176,18 +193,6 @@ func (n *DefaultOperations) FGetAttr(ctx context.Context, f FileHandle, out *fus
return
fuse
.
ENOSYS
}
func
(
n
*
DefaultOperations
)
SetAttr
(
ctx
context
.
Context
,
in
*
fuse
.
SetAttrIn
,
out
*
fuse
.
AttrOut
)
fuse
.
Status
{
return
fuse
.
ENOSYS
}
func
(
n
*
DefaultOperations
)
FSetAttr
(
ctx
context
.
Context
,
f
FileHandle
,
in
*
fuse
.
SetAttrIn
,
out
*
fuse
.
AttrOut
)
fuse
.
Status
{
if
f
!=
nil
{
return
f
.
SetAttr
(
ctx
,
in
,
out
)
}
return
fuse
.
ENOSYS
}
func
(
n
*
DefaultOperations
)
Open
(
ctx
context
.
Context
,
flags
uint32
)
(
fh
FileHandle
,
fuseFlags
uint32
,
status
fuse
.
Status
)
{
return
nil
,
0
,
fuse
.
ENOSYS
}
...
...
@@ -211,10 +216,6 @@ func (n *DefaultOperations) RemoveXAttr(ctx context.Context, attr string) fuse.S
return
fuse
.
ENOATTR
}
func
(
n
*
DefaultOperations
)
Access
(
ctx
context
.
Context
,
mask
uint32
)
fuse
.
Status
{
return
fuse
.
ENOSYS
}
func
(
n
*
DefaultOperations
)
ListXAttr
(
ctx
context
.
Context
,
dest
[]
byte
)
(
uint32
,
fuse
.
Status
)
{
return
0
,
fuse
.
OK
}
...
...
@@ -260,23 +261,6 @@ func (f *DefaultFile) SetAttr(ctx context.Context, in *fuse.SetAttrIn, out *fuse
return
fuse
.
ENOSYS
}
func
(
f
*
DefaultFile
)
Truncate
(
ctx
context
.
Context
,
size
uint64
)
fuse
.
Status
{
return
fuse
.
ENOSYS
}
func
(
f
*
DefaultFile
)
Chown
(
ctx
context
.
Context
,
uid
uint32
,
gid
uint32
)
fuse
.
Status
{
return
fuse
.
ENOSYS
}
func
(
f
*
DefaultFile
)
Chmod
(
ctx
context
.
Context
,
perms
uint32
)
fuse
.
Status
{
return
fuse
.
ENOSYS
}
func
(
f
*
DefaultFile
)
Utimens
(
ctx
context
.
Context
,
atime
*
time
.
Time
,
mtime
*
time
.
Time
)
fuse
.
Status
{
return
fuse
.
ENOSYS
}
func
(
f
*
DefaultFile
)
Allocate
(
ctx
context
.
Context
,
off
uint64
,
size
uint64
,
mode
uint32
)
(
status
fuse
.
Status
)
{
return
fuse
.
ENOSYS
}
...
...
nodefs/simple_test.go
View file @
2f9c4b1d
...
...
@@ -682,3 +682,5 @@ func TestGetAttrParallel(t *testing.T) {
}
wg
.
Wait
()
}
// XXX test mknod.
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