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
f9ab0286
Commit
f9ab0286
authored
Sep 05, 2011
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use Inode arguments in FileSystemConnector.{Mount,Unmount}.
parent
70a92e3a
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
81 additions
and
80 deletions
+81
-80
fuse/fsconnector.go
fuse/fsconnector.go
+22
-40
fuse/fsmount.go
fuse/fsmount.go
+16
-0
fuse/loopback_test.go
fuse/loopback_test.go
+5
-3
fuse/mount_test.go
fuse/mount_test.go
+10
-20
unionfs/autounion.go
unionfs/autounion.go
+23
-14
zipfs/multizip.go
zipfs/multizip.go
+5
-3
No files found.
fuse/fsconnector.go
View file @
f9ab0286
...
...
@@ -45,7 +45,7 @@ func NewFileSystemConnector(nodeFs NodeFileSystem, opts *FileSystemOptions) (me
me
.
rootNode
=
me
.
newInode
(
true
)
me
.
rootNode
.
nodeId
=
FUSE_ROOT_ID
me
.
verify
()
me
.
m
ountRoot
(
nodeFs
,
opts
)
me
.
M
ountRoot
(
nodeFs
,
opts
)
return
me
}
...
...
@@ -223,6 +223,12 @@ func (me *FileSystemConnector) findInode(fullPath string) *Inode {
////////////////////////////////////////////////////////////////
func
(
me
*
FileSystemConnector
)
MountRoot
(
nodeFs
NodeFileSystem
,
opts
*
FileSystemOptions
)
{
me
.
rootNode
.
mountFs
(
nodeFs
,
opts
)
nodeFs
.
Mount
(
me
)
me
.
verify
()
}
// Mount() generates a synthetic directory node, and mounts the file
// system there. If opts is nil, the mount options of the root file
// system are inherited. The encompassing filesystem should pretend
...
...
@@ -239,25 +245,10 @@ func (me *FileSystemConnector) findInode(fullPath string) *Inode {
// mount management in FileSystemConnector, so AutoUnionFs and
// MultiZipFs don't have to do it separately, with the risk of
// inconsistencies.
func
(
me
*
FileSystemConnector
)
Mount
(
mountPoint
string
,
nodeFs
NodeFileSystem
,
opts
*
FileSystemOptions
)
Status
{
if
mountPoint
==
"/"
||
mountPoint
==
""
{
me
.
mountRoot
(
nodeFs
,
opts
)
return
OK
}
dirParent
,
base
:=
filepath
.
Split
(
mountPoint
)
parent
:=
me
.
findInode
(
dirParent
)
if
parent
==
nil
{
log
.
Println
(
"Could not find mountpoint parent:"
,
dirParent
)
return
ENOENT
}
func
(
me
*
FileSystemConnector
)
Mount
(
parent
*
Inode
,
name
string
,
nodeFs
NodeFileSystem
,
opts
*
FileSystemOptions
)
Status
{
parent
.
treeLock
.
Lock
()
defer
parent
.
treeLock
.
Unlock
()
if
parent
.
mount
==
nil
{
return
ENOENT
}
node
:=
parent
.
children
[
base
]
node
:=
parent
.
children
[
name
]
if
node
!=
nil
{
return
EBUSY
}
...
...
@@ -268,51 +259,42 @@ func (me *FileSystemConnector) Mount(mountPoint string, nodeFs NodeFileSystem, o
}
node
.
mountFs
(
nodeFs
,
opts
)
parent
.
addChild
(
bas
e
,
node
)
parent
.
addChild
(
nam
e
,
node
)
if
parent
.
mounts
==
nil
{
parent
.
mounts
=
make
(
map
[
string
]
*
fileSystemMount
)
}
parent
.
mounts
[
base
]
=
node
.
mountPoint
parent
.
mounts
[
name
]
=
node
.
mountPoint
node
.
mountPoint
.
parentInode
=
parent
if
me
.
Debug
{
log
.
Println
(
"Mount: "
,
nodeFs
,
"on
dir"
,
mountPoint
,
"parent"
,
parent
)
log
.
Println
(
"Mount: "
,
nodeFs
,
"on
subdir"
,
name
,
"parent"
,
parent
.
nodeId
)
}
nodeFs
.
Mount
(
me
)
me
.
verify
()
return
OK
}
func
(
me
*
FileSystemConnector
)
mountRoot
(
nodeFs
NodeFileSystem
,
opts
*
FileSystemOptions
)
{
me
.
rootNode
.
mountFs
(
nodeFs
,
opts
)
nodeFs
.
Mount
(
me
)
me
.
verify
()
}
// Unmount() tries to unmount the given path.
// Unmount() tries to unmount the given inode.
//
// Returns the following error codes:
//
// EINVAL: path does not exist, or is not a mount point.
//
// EBUSY: there are open files, or submounts below this node.
func
(
me
*
FileSystemConnector
)
Unmount
(
path
string
)
Status
{
dir
,
name
:=
filepath
.
Split
(
path
)
parentNode
:=
me
.
findInode
(
dir
)
if
parentNode
==
nil
{
log
.
Println
(
"Could not find parent of mountpoint:"
,
path
)
func
(
me
*
FileSystemConnector
)
Unmount
(
node
*
Inode
)
Status
{
if
node
.
mountPoint
==
nil
{
log
.
Println
(
"not a mountpoint:"
,
node
.
nodeId
)
return
EINVAL
}
// Must lock parent to update tree structure.
parentNode
:=
node
.
mountPoint
.
parentInode
parentNode
.
treeLock
.
Lock
()
defer
parentNode
.
treeLock
.
Unlock
()
mount
:=
parentNode
.
mounts
[
name
]
if
mount
==
nil
{
return
EINVAL
}
mount
:=
node
.
mountPoint
name
:=
node
.
mountPoint
.
mountName
()
if
mount
.
openFiles
.
Count
()
>
0
{
return
EBUSY
}
...
...
fuse/fsmount.go
View file @
f9ab0286
...
...
@@ -25,6 +25,9 @@ type fileSystemMount struct {
// Node that we were mounted on.
mountInode
*
Inode
// Parent to the mountInode.
parentInode
*
Inode
// Options for the mount.
options
*
FileSystemOptions
...
...
@@ -36,6 +39,19 @@ type fileSystemMount struct {
openFiles
HandleMap
}
// Must called with lock for parent held.
func
(
me
*
fileSystemMount
)
mountName
()
string
{
for
k
,
v
:=
range
me
.
parentInode
.
mounts
{
if
me
==
v
{
return
k
}
}
panic
(
"not found"
)
return
""
}
func
(
me
*
fileSystemMount
)
setOwner
(
attr
*
Attr
)
{
if
me
.
options
.
Owner
!=
nil
{
attr
.
Owner
=
*
me
.
options
.
Owner
...
...
fuse/loopback_test.go
View file @
f9ab0286
...
...
@@ -33,6 +33,7 @@ type testCase struct {
origSubdir
string
tester
*
testing
.
T
state
*
MountState
nodeFs
*
PathNodeFs
connector
*
FileSystemConnector
}
...
...
@@ -68,8 +69,8 @@ func NewTestCase(t *testing.T) *testCase {
pfs
=
NewLockingFileSystem
(
pfs
)
var
rfs
RawFileSystem
nfs
:
=
NewPathNodeFs
(
pfs
)
me
.
connector
=
NewFileSystemConnector
(
nf
s
,
me
.
nodeFs
=
NewPathNodeFs
(
pfs
)
me
.
connector
=
NewFileSystemConnector
(
me
.
nodeF
s
,
&
FileSystemOptions
{
EntryTimeout
:
testTtl
,
AttrTimeout
:
testTtl
,
...
...
@@ -99,7 +100,8 @@ func (me *testCase) Cleanup() {
os
.
Remove
(
me
.
tmpDir
)
}
func
(
me
*
testCase
)
writeOrigFile
()
{
func
(
me
*
testCase
)
rootNode
()
*
Inode
{
return
me
.
nodeFs
.
Root
()
.
Inode
()
}
////////////////
...
...
fuse/mount_test.go
View file @
f9ab0286
...
...
@@ -16,35 +16,25 @@ func TestMountOnExisting(t *testing.T) {
err
:=
os
.
Mkdir
(
ts
.
mnt
+
"/mnt"
,
0777
)
CheckSuccess
(
err
)
nfs
:=
&
DefaultNodeFileSystem
{}
code
:=
ts
.
connector
.
Mount
(
"/
mnt"
,
nfs
,
nil
)
code
:=
ts
.
connector
.
Mount
(
ts
.
rootNode
(),
"
mnt"
,
nfs
,
nil
)
if
code
!=
EBUSY
{
t
.
Fatal
(
"expect EBUSY:"
,
code
)
}
err
=
os
.
Remove
(
ts
.
mnt
+
"/mnt"
)
CheckSuccess
(
err
)
code
=
ts
.
connector
.
Mount
(
"/
mnt"
,
nfs
,
nil
)
code
=
ts
.
connector
.
Mount
(
ts
.
rootNode
(),
"
mnt"
,
nfs
,
nil
)
if
!
code
.
Ok
()
{
t
.
Fatal
(
"expect OK:"
,
code
)
}
}
func
TestUnmountNoExist
(
t
*
testing
.
T
)
{
ts
:=
NewTestCase
(
t
)
defer
ts
.
Cleanup
()
code
:=
ts
.
connector
.
Unmount
(
"/doesnotexist"
)
if
code
!=
EINVAL
{
t
.
Fatal
(
"expect EINVAL"
,
code
)
}
}
func
TestMountRename
(
t
*
testing
.
T
)
{
ts
:=
NewTestCase
(
t
)
defer
ts
.
Cleanup
()
fs
:=
NewPathNodeFs
(
NewLoopbackFileSystem
(
ts
.
orig
))
code
:=
ts
.
connector
.
Mount
(
"/
mnt"
,
fs
,
nil
)
code
:=
ts
.
connector
.
Mount
(
ts
.
rootNode
(),
"
mnt"
,
fs
,
nil
)
if
!
code
.
Ok
()
{
t
.
Fatal
(
"mount should succeed"
)
}
...
...
@@ -59,7 +49,7 @@ func TestMountReaddir(t *testing.T) {
defer
ts
.
Cleanup
()
fs
:=
NewPathNodeFs
(
NewLoopbackFileSystem
(
ts
.
orig
))
code
:=
ts
.
connector
.
Mount
(
"/
mnt"
,
fs
,
nil
)
code
:=
ts
.
connector
.
Mount
(
ts
.
rootNode
(),
"
mnt"
,
fs
,
nil
)
if
!
code
.
Ok
()
{
t
.
Fatal
(
"mount should succeed"
)
}
...
...
@@ -79,7 +69,7 @@ func TestRecursiveMount(t *testing.T) {
CheckSuccess
(
err
)
fs
:=
NewPathNodeFs
(
NewLoopbackFileSystem
(
ts
.
orig
))
code
:=
ts
.
connector
.
Mount
(
"/
mnt"
,
fs
,
nil
)
code
:=
ts
.
connector
.
Mount
(
ts
.
rootNode
(),
"
mnt"
,
fs
,
nil
)
if
!
code
.
Ok
()
{
t
.
Fatal
(
"mount should succeed"
)
}
...
...
@@ -93,7 +83,7 @@ func TestRecursiveMount(t *testing.T) {
f
,
err
:=
os
.
Open
(
filepath
.
Join
(
submnt
,
"hello.txt"
))
CheckSuccess
(
err
)
log
.
Println
(
"Attempting unmount, should fail"
)
code
=
ts
.
connector
.
Unmount
(
"/mnt"
)
code
=
ts
.
connector
.
Unmount
(
ts
.
nodeFs
.
Node
(
"mnt"
)
)
if
code
!=
EBUSY
{
t
.
Error
(
"expect EBUSY"
)
}
...
...
@@ -104,7 +94,7 @@ func TestRecursiveMount(t *testing.T) {
time
.
Sleep
(
1.5e9
*
testTtl
)
log
.
Println
(
"Attempting unmount, should succeed"
)
code
=
ts
.
connector
.
Unmount
(
"/mnt"
)
code
=
ts
.
connector
.
Unmount
(
ts
.
nodeFs
.
Node
(
"mnt"
)
)
if
code
!=
OK
{
t
.
Error
(
"umount failed."
,
code
)
}
...
...
@@ -116,7 +106,7 @@ func TestDeletedUnmount(t *testing.T) {
submnt
:=
filepath
.
Join
(
ts
.
mnt
,
"mnt"
)
pfs2
:=
NewPathNodeFs
(
NewLoopbackFileSystem
(
ts
.
orig
))
code
:=
ts
.
connector
.
Mount
(
"/
mnt"
,
pfs2
,
nil
)
code
:=
ts
.
connector
.
Mount
(
ts
.
rootNode
(),
"
mnt"
,
pfs2
,
nil
)
if
!
code
.
Ok
()
{
t
.
Fatal
(
"Mount error"
,
code
)
}
...
...
@@ -131,14 +121,14 @@ func TestDeletedUnmount(t *testing.T) {
_
,
err
=
f
.
Write
([]
byte
(
"bla"
))
CheckSuccess
(
err
)
code
=
ts
.
connector
.
Unmount
(
"/mnt"
)
code
=
ts
.
connector
.
Unmount
(
ts
.
nodeFs
.
Node
(
"mnt"
)
)
if
code
!=
EBUSY
{
t
.
Error
(
"expect EBUSY for unmount with open files"
,
code
)
}
f
.
Close
()
time
.
Sleep
(
1.5e9
*
testTtl
)
code
=
ts
.
connector
.
Unmount
(
"/mnt"
)
code
=
ts
.
connector
.
Unmount
(
ts
.
nodeFs
.
Node
(
"mnt"
)
)
if
!
code
.
Ok
()
{
t
.
Error
(
"should succeed"
,
code
)
}
...
...
unionfs/autounion.go
View file @
f9ab0286
...
...
@@ -3,16 +3,21 @@ package unionfs
import
(
"fmt"
"github.com/hanwen/go-fuse/fuse"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"syscall"
"sync"
"syscall"
"time"
"io/ioutil"
)
type
knownFs
struct
{
*
UnionFs
*
fuse
.
PathNodeFs
}
// Creates unions for all files under a given directory,
// walking the tree and looking for directories D which have a
// D/READONLY symlink.
...
...
@@ -22,12 +27,12 @@ type AutoUnionFs struct {
fuse
.
DefaultFileSystem
lock
sync
.
RWMutex
knownFileSystems
map
[
string
]
*
Unio
nFs
knownFileSystems
map
[
string
]
know
nFs
nameRootMap
map
[
string
]
string
root
string
connector
*
fuse
.
FileSystemConnector
nodeFs
*
fuse
.
PathNodeFs
options
*
AutoUnionFsOptions
}
...
...
@@ -50,7 +55,7 @@ const (
func
NewAutoUnionFs
(
directory
string
,
options
AutoUnionFsOptions
)
*
AutoUnionFs
{
a
:=
new
(
AutoUnionFs
)
a
.
knownFileSystems
=
make
(
map
[
string
]
*
Unio
nFs
)
a
.
knownFileSystems
=
make
(
map
[
string
]
know
nFs
)
a
.
nameRootMap
=
make
(
map
[
string
]
string
)
a
.
options
=
&
options
directory
,
err
:=
filepath
.
Abs
(
directory
)
...
...
@@ -66,6 +71,7 @@ func (me *AutoUnionFs) Name() string {
}
func
(
me
*
AutoUnionFs
)
Mount
(
nodeFs
*
fuse
.
PathNodeFs
,
connector
*
fuse
.
FileSystemConnector
)
{
me
.
nodeFs
=
nodeFs
me
.
connector
=
connector
if
me
.
options
.
UpdateOnMount
{
time
.
AfterFunc
(
0.1e9
,
func
()
{
me
.
updateKnownFses
()
})
...
...
@@ -93,8 +99,8 @@ func (me *AutoUnionFs) createFs(name string, roots []string) fuse.Status {
}
}
ufs
:=
me
.
knownFileSystems
[
name
]
if
uf
s
!=
nil
{
known
:=
me
.
knownFileSystems
[
name
]
if
known
.
UnionF
s
!=
nil
{
log
.
Println
(
"Already have a workspace:"
,
name
)
return
fuse
.
EBUSY
}
...
...
@@ -107,9 +113,12 @@ func (me *AutoUnionFs) createFs(name string, roots []string) fuse.Status {
log
.
Printf
(
"Adding workspace %v for roots %v"
,
name
,
ufs
.
Name
())
nfs
:=
fuse
.
NewPathNodeFs
(
ufs
)
code
:=
me
.
connector
.
Mount
(
"/"
+
name
,
nfs
,
&
me
.
options
.
FileSystemOptions
)
code
:=
me
.
connector
.
Mount
(
me
.
nodeFs
.
Root
()
.
Inode
(),
name
,
nfs
,
&
me
.
options
.
FileSystemOptions
)
if
code
.
Ok
()
{
me
.
knownFileSystems
[
name
]
=
ufs
me
.
knownFileSystems
[
name
]
=
knownFs
{
ufs
,
nfs
,
}
me
.
nameRootMap
[
name
]
=
roots
[
0
]
}
return
code
...
...
@@ -119,14 +128,14 @@ func (me *AutoUnionFs) rmFs(name string) (code fuse.Status) {
me
.
lock
.
Lock
()
defer
me
.
lock
.
Unlock
()
fs
:=
me
.
knownFileSystems
[
name
]
if
f
s
==
nil
{
known
:=
me
.
knownFileSystems
[
name
]
if
known
.
UnionF
s
==
nil
{
return
fuse
.
ENOENT
}
code
=
me
.
connector
.
Unmount
(
name
)
code
=
me
.
connector
.
Unmount
(
known
.
PathNodeFs
.
Root
()
.
Inode
()
)
if
code
.
Ok
()
{
me
.
knownFileSystems
[
name
]
=
nil
,
false
me
.
knownFileSystems
[
name
]
=
knownFs
{}
,
false
me
.
nameRootMap
[
name
]
=
""
,
false
}
else
{
log
.
Printf
(
"Unmount failed for %s. Code %v"
,
name
,
code
)
...
...
@@ -208,7 +217,7 @@ func (me *AutoUnionFs) Readlink(path string, context *fuse.Context) (out string,
func
(
me
*
AutoUnionFs
)
getUnionFs
(
name
string
)
*
UnionFs
{
me
.
lock
.
RLock
()
defer
me
.
lock
.
RUnlock
()
return
me
.
knownFileSystems
[
name
]
return
me
.
knownFileSystems
[
name
]
.
UnionFs
}
func
(
me
*
AutoUnionFs
)
Symlink
(
pointedTo
string
,
linkName
string
,
context
*
fuse
.
Context
)
(
code
fuse
.
Status
)
{
...
...
zipfs/multizip.go
View file @
f9ab0286
...
...
@@ -35,6 +35,7 @@ type MultiZipFs struct {
zips
map
[
string
]
*
MemTreeFs
dirZipFileMap
map
[
string
]
string
nodeFs
*
fuse
.
PathNodeFs
fuse
.
DefaultFileSystem
}
...
...
@@ -50,6 +51,7 @@ func (me *MultiZipFs) Name() string {
}
func
(
me
*
MultiZipFs
)
Mount
(
nodeFs
*
fuse
.
PathNodeFs
,
connector
*
fuse
.
FileSystemConnector
)
{
me
.
nodeFs
=
nodeFs
me
.
Connector
=
connector
}
...
...
@@ -119,9 +121,9 @@ func (me *MultiZipFs) Unlink(name string, context *fuse.Context) (code fuse.Stat
me
.
lock
.
Lock
()
defer
me
.
lock
.
Unlock
()
_
,
ok
:=
me
.
zips
[
basename
]
zfs
,
ok
:=
me
.
zips
[
basename
]
if
ok
{
code
=
me
.
Connector
.
Unmount
(
"/"
+
basename
)
code
=
me
.
Connector
.
Unmount
(
zfs
.
Root
()
.
Inode
()
)
if
!
code
.
Ok
()
{
return
code
}
...
...
@@ -171,7 +173,7 @@ func (me *MultiZipFs) Symlink(value string, linkName string, context *fuse.Conte
return
fuse
.
EINVAL
}
code
=
me
.
Connector
.
Mount
(
"/"
+
base
,
fs
,
nil
)
code
=
me
.
Connector
.
Mount
(
me
.
nodeFs
.
Root
()
.
Inode
(),
base
,
fs
,
nil
)
if
!
code
.
Ok
()
{
return
code
}
...
...
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