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
804ff7cc
Commit
804ff7cc
authored
Mar 22, 2019
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nodefs: move Mode into FileID and rename to NodeAttr
parent
de68ce05
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
58 additions
and
54 deletions
+58
-54
nodefs/bridge.go
nodefs/bridge.go
+16
-15
nodefs/cache_test.go
nodefs/cache_test.go
+3
-2
nodefs/default.go
nodefs/default.go
+2
-2
nodefs/inode.go
nodefs/inode.go
+19
-19
nodefs/interrupt_test.go
nodefs/interrupt_test.go
+4
-3
nodefs/loopback.go
nodefs/loopback.go
+10
-9
nodefs/loopback_linux.go
nodefs/loopback_linux.go
+2
-2
nodefs/zip_test.go
nodefs/zip_test.go
+2
-2
No files found.
nodefs/bridge.go
View file @
804ff7cc
...
...
@@ -44,7 +44,7 @@ type rawBridge struct {
}
// newInode creates creates new inode pointing to ops.
func
(
b
*
rawBridge
)
newInode
(
ops
Operations
,
mode
uint32
,
id
FileID
,
persistent
bool
)
*
Inode
{
func
(
b
*
rawBridge
)
newInode
(
ops
Operations
,
id
NodeAttr
,
persistent
bool
)
*
Inode
{
b
.
mu
.
Lock
()
defer
b
.
mu
.
Unlock
()
...
...
@@ -66,14 +66,14 @@ func (b *rawBridge) newInode(ops Operations, mode uint32, id FileID, persistent
// file
//
// dir1.Lookup("file") and dir2.Lookup("file") are executed
// simultaneously. The matching
FileID
s ensure that we return the
// simultaneously. The matching
NodeAttr
s ensure that we return the
// same node.
old
:=
b
.
nodes
[
id
.
Ino
]
if
old
!=
nil
{
return
old
}
mode
=
m
ode
&^
07777
switch
m
ode
{
id
.
Mode
=
id
.
M
ode
&^
07777
switch
id
.
M
ode
{
case
fuse
.
S_IFDIR
:
_
=
ops
.
(
DirOperations
)
case
fuse
.
S_IFLNK
:
...
...
@@ -81,18 +81,17 @@ func (b *rawBridge) newInode(ops Operations, mode uint32, id FileID, persistent
case
fuse
.
S_IFREG
:
_
=
ops
.
(
FileOperations
)
default
:
log
.
Panicf
(
"filetype %o unimplemented"
,
m
ode
)
log
.
Panicf
(
"filetype %o unimplemented"
,
id
.
M
ode
)
}
inode
:=
&
Inode
{
mode
:
mode
,
ops
:
ops
,
nodeID
:
id
,
bridge
:
b
,
persistent
:
persistent
,
parents
:
make
(
map
[
parentData
]
struct
{}),
}
if
m
ode
==
fuse
.
S_IFDIR
{
if
id
.
M
ode
==
fuse
.
S_IFDIR
{
inode
.
children
=
make
(
map
[
string
]
*
Inode
)
}
...
...
@@ -168,13 +167,15 @@ func NewNodeFS(root DirOperations, opts *Options) fuse.RawFileSystem {
bridge
.
root
=
&
Inode
{
lookupCount
:
1
,
mode
:
fuse
.
S_IFDIR
,
children
:
make
(
map
[
string
]
*
Inode
),
parents
:
nil
,
ops
:
root
,
bridge
:
bridge
,
nodeID
:
NodeAttr
{
Ino
:
1
,
Mode
:
fuse
.
S_IFDIR
,
},
}
bridge
.
root
.
nodeID
.
Ino
=
1
root
.
setInode
(
bridge
.
root
)
bridge
.
nodes
=
map
[
uint64
]
*
Inode
{
1
:
bridge
.
root
,
...
...
@@ -216,7 +217,7 @@ func (b *rawBridge) Lookup(cancel <-chan struct{}, header *fuse.InHeader, name s
b
.
addNewChild
(
parent
,
name
,
child
,
nil
,
0
,
out
)
b
.
setEntryOutTimeout
(
out
)
out
.
Mode
=
child
.
m
ode
|
(
out
.
Mode
&
07777
)
out
.
Mode
=
child
.
nodeID
.
M
ode
|
(
out
.
Mode
&
07777
)
return
fuse
.
OK
}
...
...
@@ -321,7 +322,7 @@ func (b *rawBridge) Create(cancel <-chan struct{}, input *fuse.CreateIn, name st
out
.
NodeId
=
child
.
nodeID
.
Ino
b
.
setEntryOutTimeout
(
&
out
.
EntryOut
)
out
.
Mode
=
(
out
.
Attr
.
Mode
&
07777
)
|
child
.
m
ode
out
.
Mode
=
(
out
.
Attr
.
Mode
&
07777
)
|
child
.
nodeID
.
M
ode
return
fuse
.
OK
}
...
...
@@ -355,7 +356,7 @@ func (b *rawBridge) GetAttr(cancel <-chan struct{}, input *fuse.GetAttrIn, out *
status
:=
fops
.
FGetAttr
(
ctx
,
f
,
out
)
b
.
setAttrTimeout
(
out
)
out
.
Ino
=
input
.
NodeId
out
.
Mode
=
(
out
.
Attr
.
Mode
&
07777
)
|
n
.
m
ode
out
.
Mode
=
(
out
.
Attr
.
Mode
&
07777
)
|
n
.
nodeID
.
M
ode
return
status
}
return
n
.
ops
.
GetAttr
(
ctx
,
out
)
...
...
@@ -707,12 +708,12 @@ func (b *rawBridge) ReadDirPlus(cancel <-chan struct{}, input *fuse.ReadIn, out
}
else
{
b
.
addNewChild
(
n
,
e
.
Name
,
child
,
nil
,
0
,
entryOut
)
b
.
setEntryOutTimeout
(
entryOut
)
if
(
e
.
Mode
&^
07777
)
!=
(
child
.
m
ode
&^
07777
)
{
if
(
e
.
Mode
&^
07777
)
!=
(
child
.
nodeID
.
M
ode
&^
07777
)
{
// should go back and change the
// already serialized entry
log
.
Panicf
(
"mode mismatch between readdir %o and lookup %o"
,
e
.
Mode
,
child
.
m
ode
)
log
.
Panicf
(
"mode mismatch between readdir %o and lookup %o"
,
e
.
Mode
,
child
.
nodeID
.
M
ode
)
}
entryOut
.
Mode
=
child
.
m
ode
|
(
entryOut
.
Mode
&
07777
)
entryOut
.
Mode
=
child
.
nodeID
.
M
ode
|
(
entryOut
.
Mode
&
07777
)
}
}
...
...
nodefs/cache_test.go
View file @
804ff7cc
...
...
@@ -71,13 +71,13 @@ func (r *keepCacheRoot) OnAdd() {
keepCache
:
true
,
}
f1
.
setContent
(
0
)
i
.
AddChild
(
"keep"
,
i
.
NewInode
(
f1
,
fuse
.
S_IFREG
,
FileID
{
}),
true
)
i
.
AddChild
(
"keep"
,
i
.
NewInode
(
f1
,
NodeAttr
{
Mode
:
fuse
.
S_IFREG
}),
true
)
f2
:=
&
keepCacheFile
{
keepCache
:
false
,
}
f2
.
setContent
(
0
)
i
.
AddChild
(
"nokeep"
,
i
.
NewInode
(
f2
,
fuse
.
S_IFREG
,
FileID
{
}),
true
)
i
.
AddChild
(
"nokeep"
,
i
.
NewInode
(
f2
,
NodeAttr
{
Mode
:
fuse
.
S_IFREG
}),
true
)
}
func
TestKeepCache
(
t
*
testing
.
T
)
{
...
...
@@ -94,6 +94,7 @@ func TestKeepCache(t *testing.T) {
&
fuse
.
MountOptions
{
Debug
:
testutil
.
VerboseTest
(),
})
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
...
...
nodefs/default.go
View file @
804ff7cc
...
...
@@ -38,7 +38,7 @@ var _ Operations = &DefaultOperations{}
//
// dir1.Lookup("file") and dir2.Lookup("file") are executed simultaneously.
//
// If not using
FileID
, the mapping in rawBridge does not help. So,
// If not using
NodeAttr
, the mapping in rawBridge does not help. So,
// use atomics so that only one set can win.
//
// To read node.inode atomic.LoadPointer is used, however it is not expensive
...
...
@@ -135,7 +135,7 @@ func (n *DefaultOperations) ReadDir(ctx context.Context) (DirStream, fuse.Status
for
k
,
ch
:=
range
InodeOf
(
n
)
.
Children
()
{
r
=
append
(
r
,
fuse
.
DirEntry
{
Mode
:
ch
.
Mode
(),
Name
:
k
,
Ino
:
ch
.
FileID
()
.
Ino
})
Ino
:
ch
.
NodeAttr
()
.
Ino
})
}
return
NewListDirStream
(
r
),
fuse
.
OK
}
...
...
nodefs/inode.go
View file @
804ff7cc
...
...
@@ -20,14 +20,17 @@ type parentData struct {
parent
*
Inode
}
// FileID provides a identifier for file objects defined by FUSE
// filesystems.
type
FileID
struct
{
// NodeAttr holds immutable attributes of a object in the filesystem.
type
NodeAttr
struct
{
// Each Inode has a type, which does not change over the
// lifetime of the inode, for example fuse.S_IFDIR.
Mode
uint32
// The inode number must be unique among the currently live
// 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) on Inode creation.
// number is assigned (starting at 2^63
by default
) on Inode creation.
Ino
uint64
// When reusing a previously used inode number for a new
...
...
@@ -37,8 +40,8 @@ type FileID struct {
Gen
uint64
}
// Reserved returns if the
FileID
is using reserved Inode numbers.
func
(
i
*
FileID
)
Reserved
()
bool
{
// Reserved returns if the
NodeAttr
is using reserved Inode numbers.
func
(
i
*
NodeAttr
)
Reserved
()
bool
{
return
i
.
Ino
==
1
||
i
.
Ino
==
^
uint64
(
0
)
}
...
...
@@ -47,10 +50,7 @@ func (i *FileID) Reserved() bool {
// 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
nodeID
NodeAttr
ops
Operations
bridge
*
rawBridge
...
...
@@ -100,14 +100,14 @@ func (n *Inode) linkOps() SymlinkOperations {
return
n
.
ops
.
(
SymlinkOperations
)
}
//
FileID
returns the (Ino, Gen) tuple for this node.
func
(
n
*
Inode
)
FileID
()
FileID
{
//
NodeAttr
returns the (Ino, Gen) tuple for this node.
func
(
n
*
Inode
)
NodeAttr
()
NodeAttr
{
return
n
.
nodeID
}
// Mode returns the filetype
func
(
n
*
Inode
)
Mode
()
uint32
{
return
n
.
m
ode
return
n
.
nodeID
.
M
ode
}
// IsRoot returns true if this is the root of the FUSE mount.
...
...
@@ -271,8 +271,8 @@ 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
Operations
,
mode
uint32
,
opaque
FileID
)
*
Inode
{
return
n
.
newInode
(
node
,
mode
,
opaque
,
true
)
func
(
n
*
Inode
)
NewPersistentInode
(
node
Operations
,
id
NodeAttr
)
*
Inode
{
return
n
.
newInode
(
node
,
id
,
true
)
}
// ForgetPersistent manually marks the node as no longer important. If
...
...
@@ -287,12 +287,12 @@ func (n *Inode) ForgetPersistent() {
// 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
Operations
,
mode
uint32
,
opaqueID
FileID
)
*
Inode
{
return
n
.
newInode
(
node
,
mode
,
opaqueID
,
false
)
func
(
n
*
Inode
)
NewInode
(
node
Operations
,
id
NodeAttr
)
*
Inode
{
return
n
.
newInode
(
node
,
id
,
false
)
}
func
(
n
*
Inode
)
newInode
(
node
Operations
,
mode
uint32
,
opaqueID
FileID
,
persistent
bool
)
*
Inode
{
return
n
.
bridge
.
newInode
(
node
,
mode
,
opaqueID
,
persistent
)
func
(
n
*
Inode
)
newInode
(
node
Operations
,
id
NodeAttr
,
persistent
bool
)
*
Inode
{
return
n
.
bridge
.
newInode
(
node
,
id
,
persistent
)
}
// removeRef decreases references. Returns if this operation caused
...
...
nodefs/interrupt_test.go
View file @
804ff7cc
...
...
@@ -29,9 +29,10 @@ func (r *interruptRoot) Lookup(ctx context.Context, name string, out *fuse.Entry
if
name
!=
"file"
{
return
nil
,
fuse
.
ENOENT
}
ch
:=
InodeOf
(
r
)
.
NewInode
(
&
r
.
child
,
fuse
.
S_IFREG
,
FileID
{
Ino
:
2
,
Gen
:
1
})
ch
:=
InodeOf
(
r
)
.
NewInode
(
&
r
.
child
,
NodeAttr
{
Mode
:
fuse
.
S_IFREG
,
Ino
:
2
,
Gen
:
1
})
return
ch
,
fuse
.
OK
}
...
...
nodefs/loopback.go
View file @
804ff7cc
...
...
@@ -71,7 +71,7 @@ func (n *loopbackNode) Lookup(ctx context.Context, name string, out *fuse.EntryO
out
.
Attr
.
FromStat
(
&
st
)
node
:=
n
.
rootNode
.
newLoopbackNode
()
ch
:=
n
.
inode
()
.
NewInode
(
node
,
out
.
Attr
.
Mode
,
n
.
rootNode
.
idFromStat
(
&
st
))
ch
:=
n
.
inode
()
.
NewInode
(
node
,
n
.
rootNode
.
idFromStat
(
&
st
))
return
ch
,
fuse
.
OK
}
...
...
@@ -90,7 +90,7 @@ func (n *loopbackNode) Mknod(ctx context.Context, name string, mode, rdev uint32
out
.
Attr
.
FromStat
(
&
st
)
node
:=
n
.
rootNode
.
newLoopbackNode
()
ch
:=
n
.
inode
()
.
NewInode
(
node
,
out
.
Attr
.
Mode
,
n
.
rootNode
.
idFromStat
(
&
st
))
ch
:=
n
.
inode
()
.
NewInode
(
node
,
n
.
rootNode
.
idFromStat
(
&
st
))
return
ch
,
fuse
.
OK
}
...
...
@@ -110,7 +110,7 @@ func (n *loopbackNode) Mkdir(ctx context.Context, name string, mode uint32, out
out
.
Attr
.
FromStat
(
&
st
)
node
:=
n
.
rootNode
.
newLoopbackNode
()
ch
:=
n
.
inode
()
.
NewInode
(
node
,
out
.
Attr
.
Mode
,
n
.
rootNode
.
idFromStat
(
&
st
))
ch
:=
n
.
inode
()
.
NewInode
(
node
,
n
.
rootNode
.
idFromStat
(
&
st
))
return
ch
,
fuse
.
OK
}
...
...
@@ -147,7 +147,7 @@ func (n *loopbackNode) Rename(ctx context.Context, name string, newParent Operat
return
fuse
.
ToStatus
(
err
)
}
func
(
r
*
loopbackRoot
)
idFromStat
(
st
*
syscall
.
Stat_t
)
FileID
{
func
(
r
*
loopbackRoot
)
idFromStat
(
st
*
syscall
.
Stat_t
)
NodeAttr
{
// We compose an inode number by the underlying inode, and
// mixing in the device number. In traditional filesystems,
// the inode numbers are small. The device numbers are also
...
...
@@ -157,8 +157,9 @@ func (r *loopbackRoot) idFromStat(st *syscall.Stat_t) FileID {
// the underlying filesystem
swapped
:=
(
st
.
Dev
<<
32
)
|
(
st
.
Dev
>>
32
)
swappedRootDev
:=
(
r
.
rootDev
<<
32
)
|
(
r
.
rootDev
>>
32
)
return
FileID
{
Gen
:
1
,
return
NodeAttr
{
Mode
:
st
.
Mode
,
Gen
:
1
,
// This should work well for traditional backing FSes,
// not so much for other go-fuse FS-es
Ino
:
(
swapped
^
swappedRootDev
)
^
st
.
Ino
,
...
...
@@ -180,7 +181,7 @@ func (n *loopbackNode) Create(ctx context.Context, name string, flags uint32, mo
}
node
:=
n
.
rootNode
.
newLoopbackNode
()
ch
:=
n
.
inode
()
.
NewInode
(
node
,
uint32
(
st
.
Mode
),
n
.
rootNode
.
idFromStat
(
&
st
))
ch
:=
n
.
inode
()
.
NewInode
(
node
,
n
.
rootNode
.
idFromStat
(
&
st
))
lf
:=
NewLoopbackFile
(
fd
)
return
ch
,
lf
,
0
,
fuse
.
OK
}
...
...
@@ -197,7 +198,7 @@ func (n *loopbackNode) Symlink(ctx context.Context, target, name string, out *fu
return
nil
,
fuse
.
ToStatus
(
err
)
}
node
:=
n
.
rootNode
.
newLoopbackNode
()
ch
:=
n
.
inode
()
.
NewInode
(
node
,
uint32
(
st
.
Mode
),
n
.
rootNode
.
idFromStat
(
&
st
))
ch
:=
n
.
inode
()
.
NewInode
(
node
,
n
.
rootNode
.
idFromStat
(
&
st
))
out
.
Attr
.
FromStat
(
&
st
)
return
ch
,
fuse
.
OK
...
...
@@ -217,7 +218,7 @@ func (n *loopbackNode) Link(ctx context.Context, target Operations, name string,
return
nil
,
fuse
.
ToStatus
(
err
)
}
node
:=
n
.
rootNode
.
newLoopbackNode
()
ch
:=
n
.
inode
()
.
NewInode
(
node
,
uint32
(
st
.
Mode
),
n
.
rootNode
.
idFromStat
(
&
st
))
ch
:=
n
.
inode
()
.
NewInode
(
node
,
n
.
rootNode
.
idFromStat
(
&
st
))
out
.
Attr
.
FromStat
(
&
st
)
return
ch
,
fuse
.
OK
...
...
nodefs/loopback_linux.go
View file @
804ff7cc
...
...
@@ -48,13 +48,13 @@ func (n *loopbackNode) renameExchange(name string, newparent *loopbackNode, newN
if
err
:=
syscall
.
Fstat
(
fd1
,
&
st
);
err
!=
nil
{
return
fuse
.
ToStatus
(
err
)
}
if
!
InodeOf
(
n
)
.
IsRoot
()
&&
InodeOf
(
n
)
.
FileID
()
.
Ino
!=
n
.
rootNode
.
idFromStat
(
&
st
)
.
Ino
{
if
!
InodeOf
(
n
)
.
IsRoot
()
&&
InodeOf
(
n
)
.
NodeAttr
()
.
Ino
!=
n
.
rootNode
.
idFromStat
(
&
st
)
.
Ino
{
return
fuse
.
EBUSY
}
if
err
:=
syscall
.
Fstat
(
fd2
,
&
st
);
err
!=
nil
{
return
fuse
.
ToStatus
(
err
)
}
if
!
InodeOf
(
newparent
)
.
IsRoot
()
&&
InodeOf
(
newparent
)
.
FileID
()
.
Ino
!=
n
.
rootNode
.
idFromStat
(
&
st
)
.
Ino
{
if
!
InodeOf
(
newparent
)
.
IsRoot
()
&&
InodeOf
(
newparent
)
.
NodeAttr
()
.
Ino
!=
n
.
rootNode
.
idFromStat
(
&
st
)
.
Ino
{
return
fuse
.
EBUSY
}
...
...
nodefs/zip_test.go
View file @
804ff7cc
...
...
@@ -183,13 +183,13 @@ func (zr *zipRoot) OnAdd() {
ch
:=
p
.
GetChild
(
component
)
if
ch
==
nil
{
ch
=
InodeOf
(
zr
)
.
NewPersistentInode
(
&
DefaultOperations
{},
fuse
.
S_IFDIR
,
FileID
{
})
NodeAttr
{
Mode
:
fuse
.
S_IFDIR
})
p
.
AddChild
(
component
,
ch
,
true
)
}
p
=
ch
}
ch
:=
InodeOf
(
zr
)
.
NewPersistentInode
(
&
zipFile
{
file
:
f
},
fuse
.
S_IFREG
,
FileID
{
})
ch
:=
InodeOf
(
zr
)
.
NewPersistentInode
(
&
zipFile
{
file
:
f
},
NodeAttr
{
Mode
:
fuse
.
S_IFREG
})
p
.
AddChild
(
base
,
ch
,
true
)
}
}
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