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
Kirill Smelkov
go-fuse
Commits
0c1f5aa9
Commit
0c1f5aa9
authored
Feb 22, 2019
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nodefs: move bridge.mu section under Inode critical section
parent
1433ae4f
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
37 additions
and
26 deletions
+37
-26
nodefs/bridge.go
nodefs/bridge.go
+14
-13
nodefs/files.go
nodefs/files.go
+6
-6
nodefs/inode.go
nodefs/inode.go
+17
-7
No files found.
nodefs/bridge.go
View file @
0c1f5aa9
...
@@ -29,6 +29,8 @@ type rawBridge struct {
...
@@ -29,6 +29,8 @@ type rawBridge struct {
options
Options
options
Options
root
*
Inode
root
*
Inode
// mu protects the following data. Locks for inodes must be
// taken before rawBridge.mu
mu
sync
.
Mutex
mu
sync
.
Mutex
nodes
[]
mapEntry
nodes
[]
mapEntry
free
[]
uint64
free
[]
uint64
...
@@ -89,16 +91,14 @@ func (b *rawBridge) Lookup(header *fuse.InHeader, name string, out *fuse.EntryOu
...
@@ -89,16 +91,14 @@ func (b *rawBridge) Lookup(header *fuse.InHeader, name string, out *fuse.EntryOu
lockNodes
(
parent
,
child
)
lockNodes
(
parent
,
child
)
parent
.
setEntry
(
name
,
child
)
parent
.
setEntry
(
name
,
child
)
unlockNodes
(
parent
,
child
)
b
.
mu
.
Lock
()
b
.
mu
.
Lock
()
if
child
.
nodeID
==
0
{
if
child
.
nodeID
==
0
{
b
.
registerInode
(
child
)
b
.
registerInode
(
child
)
}
}
out
.
NodeId
=
child
.
nodeID
out
.
NodeId
=
child
.
nodeID
b
.
mu
.
Unlock
()
out
.
Generation
=
b
.
nodes
[
out
.
NodeId
]
.
generation
out
.
Generation
=
b
.
nodes
[
out
.
NodeId
]
.
generation
b
.
mu
.
Unlock
()
unlockNodes
(
parent
,
child
)
if
b
.
options
.
AttrTimeout
!=
nil
{
if
b
.
options
.
AttrTimeout
!=
nil
{
out
.
SetAttrTimeout
(
*
b
.
options
.
AttrTimeout
)
out
.
SetAttrTimeout
(
*
b
.
options
.
AttrTimeout
)
...
@@ -110,7 +110,8 @@ func (b *rawBridge) Lookup(header *fuse.InHeader, name string, out *fuse.EntryOu
...
@@ -110,7 +110,8 @@ func (b *rawBridge) Lookup(header *fuse.InHeader, name string, out *fuse.EntryOu
return
fuse
.
OK
return
fuse
.
OK
}
}
// registerInode sets an inode number in the child. Must have bridge.mu
// registerInode sets an nodeID in the child. Must have bridge.mu and
// child.mu
func
(
b
*
rawBridge
)
registerInode
(
child
*
Inode
)
{
func
(
b
*
rawBridge
)
registerInode
(
child
*
Inode
)
{
if
l
:=
len
(
b
.
free
);
l
>
0
{
if
l
:=
len
(
b
.
free
);
l
>
0
{
last
:=
b
.
free
[
l
-
1
]
last
:=
b
.
free
[
l
-
1
]
...
@@ -141,17 +142,15 @@ func (b *rawBridge) Create(input *fuse.CreateIn, name string, out *fuse.CreateOu
...
@@ -141,17 +142,15 @@ func (b *rawBridge) Create(input *fuse.CreateIn, name string, out *fuse.CreateOu
lockNodes
(
parent
,
child
)
lockNodes
(
parent
,
child
)
parent
.
setEntry
(
name
,
child
)
parent
.
setEntry
(
name
,
child
)
unlockNodes
(
parent
,
child
)
b
.
mu
.
Lock
()
b
.
mu
.
Lock
()
if
child
.
nodeID
==
0
{
if
child
.
nodeID
==
0
{
b
.
registerInode
(
child
)
b
.
registerInode
(
child
)
}
}
out
.
Fh
=
b
.
registerFile
(
f
)
out
.
Fh
=
b
.
registerFile
(
f
)
b
.
mu
.
Unlock
()
out
.
NodeId
=
child
.
nodeID
out
.
NodeId
=
child
.
nodeID
out
.
Generation
=
b
.
nodes
[
child
.
nodeID
]
.
generation
out
.
Generation
=
b
.
nodes
[
child
.
nodeID
]
.
generation
b
.
mu
.
Unlock
()
unlockNodes
(
parent
,
child
)
if
b
.
options
.
AttrTimeout
!=
nil
{
if
b
.
options
.
AttrTimeout
!=
nil
{
out
.
SetAttrTimeout
(
*
b
.
options
.
AttrTimeout
)
out
.
SetAttrTimeout
(
*
b
.
options
.
AttrTimeout
)
...
@@ -171,10 +170,12 @@ func (b *rawBridge) Forget(nodeid, nlookup uint64) {
...
@@ -171,10 +170,12 @@ func (b *rawBridge) Forget(nodeid, nlookup uint64) {
n
:=
b
.
nodes
[
nodeid
]
.
inode
n
:=
b
.
nodes
[
nodeid
]
.
inode
b
.
mu
.
Unlock
()
b
.
mu
.
Unlock
()
if
forgotten
,
_
:=
n
.
removeRef
(
nlookup
,
false
);
forgotten
{
n
.
removeRef
(
nlookup
,
false
)
b
.
free
=
append
(
b
.
free
,
nodeid
)
}
b
.
nodes
[
nodeid
]
.
inode
=
nil
}
func
(
b
*
rawBridge
)
unregisterNode
(
nodeid
uint64
)
{
b
.
free
=
append
(
b
.
free
,
nodeid
)
b
.
nodes
[
nodeid
]
.
inode
=
nil
}
}
func
(
b
*
rawBridge
)
SetDebug
(
debug
bool
)
{}
func
(
b
*
rawBridge
)
SetDebug
(
debug
bool
)
{}
...
...
nodefs/files.go
View file @
0c1f5aa9
...
@@ -77,15 +77,15 @@ func (f *loopbackFile) Fsync(ctx context.Context, flags int) (code fuse.Status)
...
@@ -77,15 +77,15 @@ func (f *loopbackFile) Fsync(ctx context.Context, flags int) (code fuse.Status)
}
}
const
(
const
(
F
_OFD_GETLK
=
36
_OFD_GETLK
=
36
F
_OFD_SETLK
=
37
_OFD_SETLK
=
37
F
_OFD_SETLKW
=
38
_OFD_SETLKW
=
38
)
)
func
(
f
*
loopbackFile
)
GetLk
(
ctx
context
.
Context
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
,
out
*
fuse
.
FileLock
)
(
code
fuse
.
Status
)
{
func
(
f
*
loopbackFile
)
GetLk
(
ctx
context
.
Context
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
,
out
*
fuse
.
FileLock
)
(
code
fuse
.
Status
)
{
flk
:=
syscall
.
Flock_t
{}
flk
:=
syscall
.
Flock_t
{}
lk
.
ToFlockT
(
&
flk
)
lk
.
ToFlockT
(
&
flk
)
code
=
fuse
.
ToStatus
(
syscall
.
FcntlFlock
(
f
.
File
.
Fd
(),
F
_OFD_GETLK
,
&
flk
))
code
=
fuse
.
ToStatus
(
syscall
.
FcntlFlock
(
f
.
File
.
Fd
(),
_OFD_GETLK
,
&
flk
))
out
.
FromFlockT
(
&
flk
)
out
.
FromFlockT
(
&
flk
)
return
return
}
}
...
@@ -120,9 +120,9 @@ func (f *loopbackFile) setLock(ctx context.Context, owner uint64, lk *fuse.FileL
...
@@ -120,9 +120,9 @@ func (f *loopbackFile) setLock(ctx context.Context, owner uint64, lk *fuse.FileL
lk
.
ToFlockT
(
&
flk
)
lk
.
ToFlockT
(
&
flk
)
var
op
int
var
op
int
if
blocking
{
if
blocking
{
op
=
F
_OFD_SETLKW
op
=
_OFD_SETLKW
}
else
{
}
else
{
op
=
F
_OFD_SETLK
op
=
_OFD_SETLK
}
}
return
fuse
.
ToStatus
(
syscall
.
FcntlFlock
(
f
.
File
.
Fd
(),
op
,
&
flk
))
return
fuse
.
ToStatus
(
syscall
.
FcntlFlock
(
f
.
File
.
Fd
(),
op
,
&
flk
))
}
}
...
...
nodefs/inode.go
View file @
0c1f5aa9
...
@@ -34,7 +34,10 @@ type Inode struct {
...
@@ -34,7 +34,10 @@ type Inode struct {
// Following data is mutable.
// Following data is mutable.
// the following fields protected by bridge.mu
// mu protects the following mutable fields. When locking
// multiple Inodes, locks must be acquired using
// lockNodes/unlockNodes
mu
sync
.
Mutex
// ID of the inode; 0 if inode was forgotten. Forgotten
// ID of the inode; 0 if inode was forgotten. Forgotten
// inodes could be persistent, not yet are unlinked from
// inodes could be persistent, not yet are unlinked from
...
@@ -42,11 +45,6 @@ type Inode struct {
...
@@ -42,11 +45,6 @@ type Inode struct {
// from bridge.nodes .
// from bridge.nodes .
nodeID
uint64
nodeID
uint64
// mu protects the following mutable fields. When locking
// multiple Inodes, locks must be acquired using
// lockNodes/unlockNodes
mu
sync
.
Mutex
// persistent indicates that this node should not be removed
// persistent indicates that this node should not be removed
// from the tree, even if there are no live references. This
// from the tree, even if there are no live references. This
// must be set on creation, and can only be changed to false
// must be set on creation, and can only be changed to false
...
@@ -272,7 +270,7 @@ func (n *Inode) NewPersistentInode(node Node, mode uint32, opaque uint64) *Inode
...
@@ -272,7 +270,7 @@ func (n *Inode) NewPersistentInode(node Node, mode uint32, opaque uint64) *Inode
// it has no children, and if the kernel as no references, the nodes
// it has no children, and if the kernel as no references, the nodes
// gets removed from the tree.
// gets removed from the tree.
func
(
n
*
Inode
)
ForgetPersistent
()
{
func
(
n
*
Inode
)
ForgetPersistent
()
{
return
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 Node. The mode should be
...
@@ -350,6 +348,18 @@ retry:
...
@@ -350,6 +348,18 @@ retry:
}
}
n
.
parents
=
map
[
parentData
]
struct
{}{}
n
.
parents
=
map
[
parentData
]
struct
{}{}
n
.
changeCounter
++
n
.
changeCounter
++
if
n
.
lookupCount
!=
0
{
panic
(
"lookupCount changed"
)
}
if
n
.
nodeID
!=
0
{
n
.
bridge
.
mu
.
Lock
()
n
.
bridge
.
unregisterNode
(
n
.
nodeID
)
n
.
bridge
.
mu
.
Unlock
()
n
.
nodeID
=
0
}
unlockNodes
(
lockme
...
)
unlockNodes
(
lockme
...
)
break
break
}
}
...
...
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