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
b229cb17
Commit
b229cb17
authored
Mar 09, 2011
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move LoopbackFileSystem into core go-fuse library.
parent
c0b9bca3
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
84 additions
and
77 deletions
+84
-77
example/main.go
example/main.go
+1
-2
examplelib/Makefile
examplelib/Makefile
+1
-2
examplelib/stackfs_test.go
examplelib/stackfs_test.go
+3
-3
fuse/Makefile
fuse/Makefile
+2
-1
fuse/loopback.go
fuse/loopback.go
+53
-54
fuse/loopback_test.go
fuse/loopback_test.go
+16
-15
fuse/misc.go
fuse/misc.go
+8
-0
No files found.
example/main.go
View file @
b229cb17
...
...
@@ -2,7 +2,6 @@ package main
import
(
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/examplelib"
"fmt"
"os"
"expvar"
...
...
@@ -23,7 +22,7 @@ func main() {
}
orig
:=
flag
.
Arg
(
0
)
fs
:=
examplelib
.
NewLoopbackFileSystem
(
orig
)
fs
:=
fuse
.
NewLoopbackFileSystem
(
orig
)
conn
:=
fuse
.
NewPathFileSystemConnector
(
fs
)
state
:=
fuse
.
NewMountState
(
conn
)
state
.
Debug
=
*
debug
...
...
examplelib/Makefile
View file @
b229cb17
...
...
@@ -5,8 +5,7 @@ TARG=github.com/hanwen/go-fuse/examplelib
DEPS
=
../fuse
GOFILES
=
loopback.go
\
stackfs.go
\
GOFILES
=
stackfs.go
\
zipfs.go
\
multizip.go
\
misc.go
...
...
examplelib/stackfs_test.go
View file @
b229cb17
...
...
@@ -41,8 +41,8 @@ func (me *stackFsTestCase) Setup(t *testing.T) {
os
.
Mkdir
(
me
.
origDir2
,
0700
)
os
.
Mkdir
(
me
.
mountDir
,
0700
)
fs1
:=
fuse
.
NewPathFileSystemConnector
(
NewLoopbackFileSystem
(
me
.
origDir1
))
fs2
:=
fuse
.
NewPathFileSystemConnector
(
NewLoopbackFileSystem
(
me
.
origDir2
))
fs1
:=
fuse
.
NewPathFileSystemConnector
(
fuse
.
NewLoopbackFileSystem
(
me
.
origDir1
))
fs2
:=
fuse
.
NewPathFileSystemConnector
(
fuse
.
NewLoopbackFileSystem
(
me
.
origDir2
))
me
.
fs
=
NewSubmountFileSystem
()
...
...
@@ -154,7 +154,7 @@ func (me *stackFsTestCase) testAddRemove() {
Mode
:
0755
,
}
conn
:=
fuse
.
NewPathFileSystemConnector
(
NewLoopbackFileSystem
(
me
.
origDir1
))
conn
:=
fuse
.
NewPathFileSystemConnector
(
fuse
.
NewLoopbackFileSystem
(
me
.
origDir1
))
ok
:=
me
.
fs
.
AddFileSystem
(
"sub1"
,
conn
,
attr
)
if
ok
{
me
.
tester
.
Errorf
(
"AddFileSystem should fail"
)
...
...
fuse/Makefile
View file @
b229cb17
...
...
@@ -12,7 +12,8 @@ GOFILES=misc.go\
pathfilesystem.go
\
bufferpool.go
\
default.go
\
datafile.go
datafile.go
\
loopback.go
include
$(GOROOT)/src/Make.pkg
examplelib
/loopback.go
→
fuse
/loopback.go
View file @
b229cb17
...
...
@@ -2,10 +2,9 @@
// system. Its main purpose is to provide test coverage without
// having to build an actual synthetic filesystem.
package
examplelib
package
fuse
import
(
"github.com/hanwen/go-fuse/fuse"
"fmt"
"os"
"path"
...
...
@@ -17,7 +16,7 @@ var _ = fmt.Println
type
LoopbackFileSystem
struct
{
root
string
fuse
.
DefaultPathFilesystem
DefaultPathFilesystem
}
func
NewLoopbackFileSystem
(
root
string
)
(
out
*
LoopbackFileSystem
)
{
...
...
@@ -31,32 +30,32 @@ func (me *LoopbackFileSystem) GetPath(relPath string) string {
return
path
.
Join
(
me
.
root
,
relPath
)
}
func
(
me
*
LoopbackFileSystem
)
GetAttr
(
name
string
)
(
*
fuse
.
Attr
,
fuse
.
Status
)
{
func
(
me
*
LoopbackFileSystem
)
GetAttr
(
name
string
)
(
*
Attr
,
Status
)
{
fullPath
:=
me
.
GetPath
(
name
)
fi
,
err
:=
os
.
Lstat
(
fullPath
)
if
err
!=
nil
{
return
nil
,
fuse
.
ENOENT
return
nil
,
ENOENT
}
out
:=
new
(
fuse
.
Attr
)
fuse
.
CopyFileInfo
(
fi
,
out
)
out
:=
new
(
Attr
)
CopyFileInfo
(
fi
,
out
)
return
out
,
fuse
.
OK
return
out
,
OK
}
func
(
me
*
LoopbackFileSystem
)
OpenDir
(
name
string
)
(
stream
chan
fuse
.
DirEntry
,
status
fuse
.
Status
)
{
func
(
me
*
LoopbackFileSystem
)
OpenDir
(
name
string
)
(
stream
chan
DirEntry
,
status
Status
)
{
// What other ways beyond O_RDONLY are there to open
// directories?
f
,
err
:=
os
.
Open
(
me
.
GetPath
(
name
),
os
.
O_RDONLY
,
0
)
if
err
!=
nil
{
return
nil
,
fuse
.
OsErrorToFuseError
(
err
)
return
nil
,
OsErrorToFuseError
(
err
)
}
output
:=
make
(
chan
fuse
.
DirEntry
,
500
)
output
:=
make
(
chan
DirEntry
,
500
)
go
func
()
{
for
{
want
:=
500
infos
,
err
:=
f
.
Readdir
(
want
)
for
i
,
_
:=
range
infos
{
output
<-
fuse
.
DirEntry
{
output
<-
DirEntry
{
Name
:
infos
[
i
]
.
Name
,
Mode
:
infos
[
i
]
.
Mode
,
}
...
...
@@ -69,82 +68,82 @@ func (me *LoopbackFileSystem) OpenDir(name string) (stream chan fuse.DirEntry, s
break
}
}
output
<-
fuse
.
DirEntry
{}
output
<-
DirEntry
{}
f
.
Close
()
}()
return
output
,
fuse
.
OK
return
output
,
OK
}
func
(
me
*
LoopbackFileSystem
)
Open
(
name
string
,
flags
uint32
)
(
fuseFile
fuse
.
RawFuseFile
,
status
fuse
.
Status
)
{
func
(
me
*
LoopbackFileSystem
)
Open
(
name
string
,
flags
uint32
)
(
fuseFile
RawFuseFile
,
status
Status
)
{
f
,
err
:=
os
.
Open
(
me
.
GetPath
(
name
),
int
(
flags
),
0
)
if
err
!=
nil
{
return
nil
,
fuse
.
OsErrorToFuseError
(
err
)
return
nil
,
OsErrorToFuseError
(
err
)
}
return
&
LoopbackFile
{
file
:
f
},
fuse
.
OK
return
&
LoopbackFile
{
file
:
f
},
OK
}
func
(
me
*
LoopbackFileSystem
)
Chmod
(
path
string
,
mode
uint32
)
(
code
fuse
.
Status
)
{
func
(
me
*
LoopbackFileSystem
)
Chmod
(
path
string
,
mode
uint32
)
(
code
Status
)
{
err
:=
os
.
Chmod
(
me
.
GetPath
(
path
),
mode
)
return
fuse
.
OsErrorToFuseError
(
err
)
return
OsErrorToFuseError
(
err
)
}
func
(
me
*
LoopbackFileSystem
)
Chown
(
path
string
,
uid
uint32
,
gid
uint32
)
(
code
fuse
.
Status
)
{
return
fuse
.
OsErrorToFuseError
(
os
.
Chown
(
me
.
GetPath
(
path
),
int
(
uid
),
int
(
gid
)))
func
(
me
*
LoopbackFileSystem
)
Chown
(
path
string
,
uid
uint32
,
gid
uint32
)
(
code
Status
)
{
return
OsErrorToFuseError
(
os
.
Chown
(
me
.
GetPath
(
path
),
int
(
uid
),
int
(
gid
)))
}
func
(
me
*
LoopbackFileSystem
)
Truncate
(
path
string
,
offset
uint64
)
(
code
fuse
.
Status
)
{
return
fuse
.
OsErrorToFuseError
(
os
.
Truncate
(
me
.
GetPath
(
path
),
int64
(
offset
)))
func
(
me
*
LoopbackFileSystem
)
Truncate
(
path
string
,
offset
uint64
)
(
code
Status
)
{
return
OsErrorToFuseError
(
os
.
Truncate
(
me
.
GetPath
(
path
),
int64
(
offset
)))
}
func
(
me
*
LoopbackFileSystem
)
Utimens
(
path
string
,
AtimeNs
uint64
,
MtimeNs
uint64
)
(
code
fuse
.
Status
)
{
return
fuse
.
OsErrorToFuseError
(
os
.
Chtimes
(
me
.
GetPath
(
path
),
int64
(
AtimeNs
),
int64
(
MtimeNs
)))
func
(
me
*
LoopbackFileSystem
)
Utimens
(
path
string
,
AtimeNs
uint64
,
MtimeNs
uint64
)
(
code
Status
)
{
return
OsErrorToFuseError
(
os
.
Chtimes
(
me
.
GetPath
(
path
),
int64
(
AtimeNs
),
int64
(
MtimeNs
)))
}
func
(
me
*
LoopbackFileSystem
)
Readlink
(
name
string
)
(
out
string
,
code
fuse
.
Status
)
{
func
(
me
*
LoopbackFileSystem
)
Readlink
(
name
string
)
(
out
string
,
code
Status
)
{
f
,
err
:=
os
.
Readlink
(
me
.
GetPath
(
name
))
return
f
,
fuse
.
OsErrorToFuseError
(
err
)
return
f
,
OsErrorToFuseError
(
err
)
}
func
(
me
*
LoopbackFileSystem
)
Mknod
(
name
string
,
mode
uint32
,
dev
uint32
)
(
code
fuse
.
Status
)
{
return
fuse
.
Status
(
syscall
.
Mknod
(
me
.
GetPath
(
name
),
mode
,
int
(
dev
)))
func
(
me
*
LoopbackFileSystem
)
Mknod
(
name
string
,
mode
uint32
,
dev
uint32
)
(
code
Status
)
{
return
Status
(
syscall
.
Mknod
(
me
.
GetPath
(
name
),
mode
,
int
(
dev
)))
}
func
(
me
*
LoopbackFileSystem
)
Mkdir
(
path
string
,
mode
uint32
)
(
code
fuse
.
Status
)
{
return
fuse
.
OsErrorToFuseError
(
os
.
Mkdir
(
me
.
GetPath
(
path
),
mode
))
func
(
me
*
LoopbackFileSystem
)
Mkdir
(
path
string
,
mode
uint32
)
(
code
Status
)
{
return
OsErrorToFuseError
(
os
.
Mkdir
(
me
.
GetPath
(
path
),
mode
))
}
func
(
me
*
LoopbackFileSystem
)
Unlink
(
name
string
)
(
code
fuse
.
Status
)
{
return
fuse
.
OsErrorToFuseError
(
os
.
Remove
(
me
.
GetPath
(
name
)))
func
(
me
*
LoopbackFileSystem
)
Unlink
(
name
string
)
(
code
Status
)
{
return
OsErrorToFuseError
(
os
.
Remove
(
me
.
GetPath
(
name
)))
}
func
(
me
*
LoopbackFileSystem
)
Rmdir
(
name
string
)
(
code
fuse
.
Status
)
{
return
fuse
.
OsErrorToFuseError
(
os
.
Remove
(
me
.
GetPath
(
name
)))
func
(
me
*
LoopbackFileSystem
)
Rmdir
(
name
string
)
(
code
Status
)
{
return
OsErrorToFuseError
(
os
.
Remove
(
me
.
GetPath
(
name
)))
}
func
(
me
*
LoopbackFileSystem
)
Symlink
(
pointedTo
string
,
linkName
string
)
(
code
fuse
.
Status
)
{
return
fuse
.
OsErrorToFuseError
(
os
.
Symlink
(
pointedTo
,
me
.
GetPath
(
linkName
)))
func
(
me
*
LoopbackFileSystem
)
Symlink
(
pointedTo
string
,
linkName
string
)
(
code
Status
)
{
return
OsErrorToFuseError
(
os
.
Symlink
(
pointedTo
,
me
.
GetPath
(
linkName
)))
}
func
(
me
*
LoopbackFileSystem
)
Rename
(
oldPath
string
,
newPath
string
)
(
code
fuse
.
Status
)
{
func
(
me
*
LoopbackFileSystem
)
Rename
(
oldPath
string
,
newPath
string
)
(
code
Status
)
{
err
:=
os
.
Rename
(
me
.
GetPath
(
oldPath
),
me
.
GetPath
(
newPath
))
return
fuse
.
OsErrorToFuseError
(
err
)
return
OsErrorToFuseError
(
err
)
}
func
(
me
*
LoopbackFileSystem
)
Link
(
orig
string
,
newName
string
)
(
code
fuse
.
Status
)
{
return
fuse
.
OsErrorToFuseError
(
os
.
Link
(
me
.
GetPath
(
orig
),
me
.
GetPath
(
newName
)))
func
(
me
*
LoopbackFileSystem
)
Link
(
orig
string
,
newName
string
)
(
code
Status
)
{
return
OsErrorToFuseError
(
os
.
Link
(
me
.
GetPath
(
orig
),
me
.
GetPath
(
newName
)))
}
func
(
me
*
LoopbackFileSystem
)
Access
(
name
string
,
mode
uint32
)
(
code
fuse
.
Status
)
{
return
fuse
.
Status
(
syscall
.
Access
(
me
.
GetPath
(
name
),
mode
))
func
(
me
*
LoopbackFileSystem
)
Access
(
name
string
,
mode
uint32
)
(
code
Status
)
{
return
Status
(
syscall
.
Access
(
me
.
GetPath
(
name
),
mode
))
}
func
(
me
*
LoopbackFileSystem
)
Create
(
path
string
,
flags
uint32
,
mode
uint32
)
(
fuseFile
fuse
.
RawFuseFile
,
code
fuse
.
Status
)
{
func
(
me
*
LoopbackFileSystem
)
Create
(
path
string
,
flags
uint32
,
mode
uint32
)
(
fuseFile
RawFuseFile
,
code
Status
)
{
f
,
err
:=
os
.
Open
(
me
.
GetPath
(
path
),
int
(
flags
)
|
os
.
O_CREAT
,
mode
)
return
&
LoopbackFile
{
file
:
f
},
fuse
.
OsErrorToFuseError
(
err
)
return
&
LoopbackFile
{
file
:
f
},
OsErrorToFuseError
(
err
)
}
func
(
me
*
LoopbackFileSystem
)
SetOptions
(
options
*
fuse
.
PathFileSystemConnectorOptions
)
{
func
(
me
*
LoopbackFileSystem
)
SetOptions
(
options
*
PathFileSystemConnectorOptions
)
{
options
.
NegativeTimeout
=
100.0
options
.
AttrTimeout
=
100.0
options
.
EntryTimeout
=
100.0
...
...
@@ -155,29 +154,29 @@ func (me *LoopbackFileSystem) SetOptions(options *fuse.PathFileSystemConnectorOp
type
LoopbackFile
struct
{
file
*
os
.
File
fuse
.
DefaultRawFuseFile
DefaultRawFuseFile
}
func
(
me
*
LoopbackFile
)
Read
(
input
*
fuse
.
ReadIn
,
buffers
*
fuse
.
BufferPool
)
([]
byte
,
fuse
.
Status
)
{
func
(
me
*
LoopbackFile
)
Read
(
input
*
ReadIn
,
buffers
*
BufferPool
)
([]
byte
,
Status
)
{
slice
:=
buffers
.
AllocBuffer
(
input
.
Size
)
n
,
err
:=
me
.
file
.
ReadAt
(
slice
,
int64
(
input
.
Offset
))
if
err
==
os
.
EOF
{
// TODO - how to signal EOF?
return
slice
[
:
n
],
fuse
.
OK
return
slice
[
:
n
],
OK
}
return
slice
[
:
n
],
fuse
.
OsErrorToFuseError
(
err
)
return
slice
[
:
n
],
OsErrorToFuseError
(
err
)
}
func
(
me
*
LoopbackFile
)
Write
(
input
*
fuse
.
WriteIn
,
data
[]
byte
)
(
uint32
,
fuse
.
Status
)
{
func
(
me
*
LoopbackFile
)
Write
(
input
*
WriteIn
,
data
[]
byte
)
(
uint32
,
Status
)
{
n
,
err
:=
me
.
file
.
WriteAt
(
data
,
int64
(
input
.
Offset
))
return
uint32
(
n
),
fuse
.
OsErrorToFuseError
(
err
)
return
uint32
(
n
),
OsErrorToFuseError
(
err
)
}
func
(
me
*
LoopbackFile
)
Release
()
{
me
.
file
.
Close
()
}
func
(
me
*
LoopbackFile
)
Fsync
(
*
fuse
.
FsyncIn
)
(
code
fuse
.
Status
)
{
return
fuse
.
Status
(
syscall
.
Fsync
(
me
.
file
.
Fd
()))
func
(
me
*
LoopbackFile
)
Fsync
(
*
FsyncIn
)
(
code
Status
)
{
return
Status
(
syscall
.
Fsync
(
me
.
file
.
Fd
()))
}
examplelib
/loopback_test.go
→
fuse
/loopback_test.go
View file @
b229cb17
package
examplelib
package
fuse
import
(
"github.com/hanwen/go-fuse/fuse"
"bytes"
"fmt"
"log"
...
...
@@ -33,8 +32,8 @@ type testCase struct {
origSubdir
string
origSubfile
string
tester
*
testing
.
T
state
*
fuse
.
MountState
connector
*
fuse
.
PathFileSystemConnector
state
*
MountState
connector
*
PathFileSystemConnector
}
// Create and mount filesystem.
...
...
@@ -44,8 +43,8 @@ func (me *testCase) Setup(t *testing.T) {
const
name
string
=
"hello.txt"
const
subdir
string
=
"subdir"
me
.
origDir
=
fuse
.
MakeTempDir
()
me
.
mountPoint
=
fuse
.
MakeTempDir
()
me
.
origDir
=
MakeTempDir
()
me
.
mountPoint
=
MakeTempDir
()
me
.
mountFile
=
path
.
Join
(
me
.
mountPoint
,
name
)
me
.
mountSubdir
=
path
.
Join
(
me
.
mountPoint
,
subdir
)
...
...
@@ -55,9 +54,9 @@ func (me *testCase) Setup(t *testing.T) {
me
.
origSubfile
=
path
.
Join
(
me
.
origSubdir
,
"subfile"
)
pfs
:=
NewLoopbackFileSystem
(
me
.
origDir
)
me
.
connector
=
fuse
.
NewPathFileSystemConnector
(
pfs
)
me
.
connector
=
NewPathFileSystemConnector
(
pfs
)
me
.
connector
.
Debug
=
true
me
.
state
=
fuse
.
NewMountState
(
me
.
connector
)
me
.
state
=
NewMountState
(
me
.
connector
)
me
.
state
.
Mount
(
me
.
mountPoint
)
//me.state.Debug = false
...
...
@@ -272,10 +271,12 @@ func (me *testCase) testRename() {
err
:=
os
.
Rename
(
me
.
mountFile
,
me
.
mountSubfile
)
CheckSuccess
(
err
)
if
FileExists
(
me
.
origFile
)
{
f
,
_
:=
os
.
Lstat
(
me
.
origFile
)
if
f
!=
nil
{
me
.
tester
.
Errorf
(
"original %v still exists."
,
me
.
origFile
)
}
if
!
FileExists
(
me
.
origSubfile
)
{
f
,
_
=
os
.
Lstat
(
me
.
origSubfile
)
if
f
==
nil
{
me
.
tester
.
Errorf
(
"destination %v does not exist."
,
me
.
origSubfile
)
}
...
...
@@ -532,7 +533,7 @@ func TestRecursiveMount(t *testing.T) {
pfs2
:=
NewLoopbackFileSystem
(
ts
.
origDir
)
code
:=
ts
.
connector
.
Mount
(
"/hello.txt"
,
pfs2
)
if
code
!=
fuse
.
EINVAL
{
if
code
!=
EINVAL
{
t
.
Error
(
"expect EINVAL"
,
code
)
}
...
...
@@ -540,7 +541,7 @@ func TestRecursiveMount(t *testing.T) {
err
=
os
.
Mkdir
(
submnt
,
0777
)
CheckSuccess
(
err
)
code
=
ts
.
connector
.
Mount
(
"/mnt"
,
pfs2
)
if
code
!=
fuse
.
OK
{
if
code
!=
OK
{
t
.
Errorf
(
"mkdir"
)
}
...
...
@@ -552,17 +553,17 @@ func TestRecursiveMount(t *testing.T) {
f
,
err
=
os
.
Open
(
path
.
Join
(
submnt
,
"hello.txt"
),
os
.
O_RDONLY
,
0
)
CheckSuccess
(
err
)
code
=
ts
.
connector
.
Unmount
(
"/mnt"
)
if
code
!=
fuse
.
EBUSY
{
if
code
!=
EBUSY
{
t
.
Error
(
"expect EBUSY"
)
}
f
.
Close
()
// The close takes some time to propagate through
FUSE.
// The close takes some time to propagate through
time
.
Sleep
(
1e9
)
code
=
ts
.
connector
.
Unmount
(
"/mnt"
)
if
code
!=
fuse
.
OK
{
if
code
!=
OK
{
t
.
Error
(
"umount failed."
,
code
)
}
...
...
fuse/misc.go
View file @
b229cb17
...
...
@@ -295,3 +295,11 @@ func NegativeEntry(time float64) *EntryOut {
func
ModeToType
(
mode
uint32
)
uint32
{
return
(
mode
&
0170000
)
>>
12
}
func
CheckSuccess
(
e
os
.
Error
)
{
if
e
!=
nil
{
panic
(
fmt
.
Sprintf
(
"Unexpected error: %v"
,
e
))
}
}
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