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
d2f8777d
Commit
d2f8777d
authored
Apr 21, 2011
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Handle umount busy check using per-node open counts.
parent
0ffb4617
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
37 additions
and
32 deletions
+37
-32
fuse/pathfilesystem.go
fuse/pathfilesystem.go
+37
-32
No files found.
fuse/pathfilesystem.go
View file @
d2f8777d
...
...
@@ -18,16 +18,8 @@ type mountData struct {
// If yes, we are looking to unmount the mounted fs.
unmountPending
bool
// Count files, dirs and mounts.
openCount
int
}
func
(
me
*
mountData
)
incOpenCount
(
delta
int
)
{
me
.
mutex
.
Lock
()
defer
me
.
mutex
.
Unlock
()
me
.
openCount
+=
delta
}
func
newMount
(
fs
PathFilesystem
)
*
mountData
{
return
&
mountData
{
fs
:
fs
}
...
...
@@ -49,6 +41,16 @@ type inode struct {
mount
*
mountData
}
// Should be called with lock held.
func
(
me
*
inode
)
totalOpenCount
()
int
{
o
:=
me
.
OpenCount
for
_
,
v
:=
range
me
.
Children
{
o
+=
v
.
totalOpenCount
()
}
return
o
}
const
initDirSize
=
20
func
(
me
*
inode
)
verify
()
{
...
...
@@ -359,15 +361,20 @@ func (me *PathFileSystemConnector) Mount(mountPoint string, fs PathFilesystem) S
}
node
=
me
.
findInode
(
mountPoint
)
// TODO - check that fs was not mounted elsewhere.
if
len
(
node
.
Children
)
>
0
{
return
EBUSY
}
if
node
.
Type
&
ModeToType
(
S_IFDIR
)
==
0
{
return
EINVAL
}
me
.
lock
.
Lock
()
hasChildren
:=
len
(
node
.
Children
)
>
0
// don't use defer, as we dont want to hold the lock during
// fs.Mount().
me
.
lock
.
Unlock
()
if
hasChildren
{
return
EBUSY
}
code
:=
fs
.
Mount
(
me
)
if
code
!=
OK
{
if
me
.
Debug
{
...
...
@@ -381,9 +388,11 @@ func (me *PathFileSystemConnector) Mount(mountPoint string, fs PathFilesystem) S
}
node
.
mount
=
newMount
(
fs
)
me
.
fileLock
.
Lock
()
defer
me
.
fileLock
.
Unlock
()
if
node
.
Parent
!=
nil
{
_
,
parentMount
:=
node
.
Parent
.
GetPath
()
parentMount
.
incOpenCount
(
1
)
node
.
Parent
.
OpenCount
++
}
return
OK
...
...
@@ -400,9 +409,14 @@ func (me *PathFileSystemConnector) Unmount(path string) Status {
panic
(
path
)
}
mount
.
mutex
.
Lock
()
defer
mount
.
mutex
.
Unlock
()
if
mount
.
openCount
>
0
{
// Need to lock to look at node.Children
me
.
lock
.
RLock
()
defer
me
.
lock
.
RUnlock
()
me
.
fileLock
.
Lock
()
defer
me
.
fileLock
.
Unlock
()
if
node
.
totalOpenCount
()
>
0
{
log
.
Println
(
"Umount - busy: "
,
mount
)
return
EBUSY
}
...
...
@@ -411,6 +425,8 @@ func (me *PathFileSystemConnector) Unmount(path string) Status {
log
.
Println
(
"Unmount: "
,
mount
)
}
mount
.
mutex
.
Lock
()
defer
mount
.
mutex
.
Unlock
()
if
len
(
node
.
Children
)
>
0
{
mount
.
fs
.
Unmount
()
mount
.
unmountPending
=
true
...
...
@@ -419,8 +435,7 @@ func (me *PathFileSystemConnector) Unmount(path string) Status {
}
if
node
.
Parent
!=
nil
{
_
,
parentMount
:=
node
.
Parent
.
GetPath
()
parentMount
.
incOpenCount
(
-
1
)
node
.
Parent
.
OpenCount
--
}
return
OK
}
...
...
@@ -519,8 +534,6 @@ func (me *PathFileSystemConnector) OpenDir(header *InHeader, input *OpenIn) (fla
return
0
,
0
,
err
}
mount
.
incOpenCount
(
1
)
de
:=
new
(
FuseDir
)
de
.
stream
=
stream
...
...
@@ -551,7 +564,6 @@ func (me *PathFileSystemConnector) Open(header *InHeader, input *OpenIn) (flags
}
h
:=
me
.
registerFile
(
node
,
f
)
mount
.
incOpenCount
(
1
)
return
0
,
h
,
OK
}
...
...
@@ -731,24 +743,17 @@ func (me *PathFileSystemConnector) Create(header *InHeader, input *CreateIn, nam
}
out
,
code
,
inode
:=
me
.
internalLookupWithNode
(
parent
,
name
,
1
)
mount
.
incOpenCount
(
1
)
return
0
,
me
.
registerFile
(
inode
,
f
),
out
,
code
}
func
(
me
*
PathFileSystemConnector
)
Release
(
header
*
InHeader
,
input
*
ReleaseIn
)
{
_
,
mount
,
node
:=
me
.
GetPath
(
header
.
NodeId
)
_
,
_
,
node
:=
me
.
GetPath
(
header
.
NodeId
)
f
:=
me
.
unregisterFile
(
node
,
input
.
Fh
)
.
(
RawFuseFile
)
f
.
Release
()
if
mount
!=
nil
{
mount
.
incOpenCount
(
-
1
)
}
}
func
(
me
*
PathFileSystemConnector
)
ReleaseDir
(
header
*
InHeader
,
input
*
ReleaseIn
)
{
_
,
mount
,
node
:=
me
.
GetPath
(
header
.
NodeId
)
if
mount
!=
nil
{
mount
.
incOpenCount
(
-
1
)
}
_
,
_
,
node
:=
me
.
GetPath
(
header
.
NodeId
)
d
:=
me
.
unregisterFile
(
node
,
input
.
Fh
)
.
(
RawFuseDir
)
d
.
Release
()
}
...
...
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