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
9ec4c8af
Commit
9ec4c8af
authored
Sep 05, 2011
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rewrite zipfs to be a native NodeFileSystem
parent
f3e1921c
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
141 additions
and
179 deletions
+141
-179
fuse/fsconnector.go
fuse/fsconnector.go
+10
-0
fuse/fsops.go
fuse/fsops.go
+1
-10
fuse/inode.go
fuse/inode.go
+22
-3
fuse/pathfs.go
fuse/pathfs.go
+0
-2
zipfs/memtree.go
zipfs/memtree.go
+69
-103
zipfs/multizip.go
zipfs/multizip.go
+3
-3
zipfs/multizip_test.go
zipfs/multizip_test.go
+1
-1
zipfs/tarfs.go
zipfs/tarfs.go
+10
-21
zipfs/zipfs.go
zipfs/zipfs.go
+24
-35
zipfs/zipfs_test.go
zipfs/zipfs_test.go
+1
-1
No files found.
fuse/fsconnector.go
View file @
9ec4c8af
...
...
@@ -7,6 +7,7 @@ package fuse
import
(
"fmt"
"log"
"os"
"path/filepath"
"strings"
"unsafe"
...
...
@@ -59,6 +60,7 @@ func (me *FileSystemConnector) verify() {
func
(
me
*
FileSystemConnector
)
newInode
(
isDir
bool
)
*
Inode
{
data
:=
new
(
Inode
)
data
.
nodeId
=
me
.
inodeMap
.
Register
(
&
data
.
handled
)
data
.
connector
=
me
if
isDir
{
data
.
children
=
make
(
map
[
string
]
*
Inode
,
initDirSize
)
}
...
...
@@ -66,6 +68,14 @@ func (me *FileSystemConnector) newInode(isDir bool) *Inode {
return
data
}
func
(
me
*
FileSystemConnector
)
createChild
(
parent
*
Inode
,
name
string
,
fi
*
os
.
FileInfo
,
fsi
FsNode
)
(
out
*
EntryOut
,
child
*
Inode
)
{
child
=
parent
.
CreateChild
(
name
,
fi
.
IsDirectory
(),
fsi
)
out
=
parent
.
mount
.
fileInfoToEntry
(
fi
)
out
.
Ino
=
child
.
nodeId
out
.
NodeId
=
child
.
nodeId
return
out
,
child
}
func
(
me
*
FileSystemConnector
)
lookupUpdate
(
parent
*
Inode
,
name
string
,
isDir
bool
,
lookupCount
int
)
*
Inode
{
defer
me
.
verify
()
...
...
fuse/fsops.go
View file @
9ec4c8af
...
...
@@ -47,7 +47,7 @@ func (me *FileSystemConnector) internalLookup(parent *Inode, name string, lookup
}
var
fi
*
os
.
FileInfo
child
:=
parent
.
g
etChild
(
name
)
child
:=
parent
.
G
etChild
(
name
)
if
child
!=
nil
{
fi
,
code
=
child
.
fsInode
.
GetAttr
(
nil
,
nil
)
}
...
...
@@ -199,15 +199,6 @@ func (me *FileSystemConnector) Mknod(header *InHeader, input *MknodIn, name stri
return
out
,
code
}
func
(
me
*
FileSystemConnector
)
createChild
(
parent
*
Inode
,
name
string
,
fi
*
os
.
FileInfo
,
fsi
FsNode
)
(
out
*
EntryOut
,
child
*
Inode
)
{
child
=
parent
.
createChild
(
name
,
fi
.
IsDirectory
(),
fsi
,
me
)
out
=
parent
.
mount
.
fileInfoToEntry
(
fi
)
out
.
Ino
=
child
.
nodeId
out
.
NodeId
=
child
.
nodeId
return
out
,
child
}
func
(
me
*
FileSystemConnector
)
Mkdir
(
header
*
InHeader
,
input
*
MkdirIn
,
name
string
)
(
out
*
EntryOut
,
code
Status
)
{
parent
:=
me
.
getInodeData
(
header
.
NodeId
)
fi
,
fsInode
,
code
:=
parent
.
fsInode
.
Mkdir
(
name
,
input
.
Mode
,
&
header
.
Context
)
...
...
fuse/inode.go
View file @
9ec4c8af
...
...
@@ -41,6 +41,8 @@ type Inode struct {
// during the lifetime, except upon Unmount() when it is set
// to nil.
mount
*
fileSystemMount
connector
*
FileSystemConnector
}
// public methods.
...
...
@@ -66,6 +68,21 @@ func (me *Inode) AnyFile() (file File) {
return
file
}
func
(
me
*
Inode
)
Children
()
(
out
map
[
string
]
*
Inode
)
{
me
.
treeLock
.
Lock
()
defer
me
.
treeLock
.
Unlock
()
out
=
map
[
string
]
*
Inode
{}
for
k
,
v
:=
range
me
.
children
{
out
[
k
]
=
v
}
return
out
}
func
(
me
*
Inode
)
FsNode
()
FsNode
{
return
me
.
fsInode
}
// Returns an open writable file for the given Inode.
func
(
me
*
Inode
)
WritableFiles
()
(
files
[]
File
)
{
me
.
openFilesMutex
.
Lock
()
...
...
@@ -83,7 +100,8 @@ func (me *Inode) IsDir() bool {
return
me
.
children
!=
nil
}
func
(
me
*
Inode
)
createChild
(
name
string
,
isDir
bool
,
fsi
FsNode
,
conn
*
FileSystemConnector
)
*
Inode
{
// Creates an Inode as child.
func
(
me
*
Inode
)
CreateChild
(
name
string
,
isDir
bool
,
fsi
FsNode
)
*
Inode
{
me
.
treeLock
.
Lock
()
defer
me
.
treeLock
.
Unlock
()
...
...
@@ -91,18 +109,19 @@ func (me *Inode) createChild(name string, isDir bool, fsi FsNode, conn *FileSyst
if
ch
!=
nil
{
panic
(
fmt
.
Sprintf
(
"already have a child at %v %q"
,
me
.
nodeId
,
name
))
}
ch
=
conn
.
newInode
(
isDir
)
ch
=
me
.
connector
.
newInode
(
isDir
)
ch
.
fsInode
=
fsi
fsi
.
SetInode
(
ch
)
ch
.
mount
=
me
.
mount
ch
.
treeLock
=
me
.
treeLock
ch
.
lookupCount
=
1
ch
.
connector
=
me
.
connector
me
.
addChild
(
name
,
ch
)
return
ch
}
func
(
me
*
Inode
)
g
etChild
(
name
string
)
(
child
*
Inode
)
{
func
(
me
*
Inode
)
G
etChild
(
name
string
)
(
child
*
Inode
)
{
me
.
treeLock
.
Lock
()
defer
me
.
treeLock
.
Unlock
()
...
...
fuse/pathfs.go
View file @
9ec4c8af
...
...
@@ -8,8 +8,6 @@ import (
var
_
=
log
.
Println
type
PathNodeFs
struct
{
fs
FileSystem
root
*
pathInode
...
...
zipfs/memtree.go
View file @
9ec4c8af
...
...
@@ -5,7 +5,6 @@ import (
"github.com/hanwen/go-fuse/fuse"
"os"
"strings"
"path/filepath"
)
type
MemFile
interface
{
...
...
@@ -13,135 +12,102 @@ type MemFile interface {
Data
()
[]
byte
}
type
MemTree
struct
{
subdirs
map
[
string
]
*
MemTree
type
memNode
struct
{
fuse
.
DefaultFsNode
file
MemFile
}
type
MemTreeFs
struct
{
fuse
.
DefaultNodeFileSystem
root
memNode
files
map
[
string
]
MemFile
}
func
NewMemTree
()
*
MemTree
{
d
:=
new
(
MemTree
)
d
.
subdirs
=
make
(
map
[
string
]
*
MemTree
)
d
.
files
=
make
(
map
[
string
]
MemFile
)
func
NewMemTreeFs
()
*
MemTreeFs
{
d
:=
new
(
MemTreeFs
)
return
d
}
func
(
me
*
MemTree
)
Print
(
indent
int
)
{
s
:=
""
for
i
:=
0
;
i
<
indent
;
i
++
{
s
=
s
+
" "
}
for
k
,
v
:=
range
me
.
subdirs
{
fmt
.
Println
(
s
+
k
+
":"
)
v
.
Print
(
indent
+
2
)
func
(
me
*
MemTreeFs
)
Mount
(
conn
*
fuse
.
FileSystemConnector
)
{
for
k
,
v
:=
range
me
.
files
{
me
.
addFile
(
k
,
v
)
}
for
k
,
_
:=
range
me
.
files
{
fmt
.
Println
(
s
+
k
)
}
me
.
files
=
nil
}
func
(
me
*
MemTree
)
Lookup
(
name
string
)
(
*
MemTree
,
MemFile
)
{
if
name
==
""
{
return
me
,
nil
}
parent
:=
me
comps
:=
strings
.
Split
(
filepath
.
Clean
(
name
),
"/"
)
for
_
,
c
:=
range
comps
[
:
len
(
comps
)
-
1
]
{
parent
=
parent
.
subdirs
[
c
]
if
parent
==
nil
{
return
nil
,
nil
}
}
base
:=
comps
[
len
(
comps
)
-
1
]
file
,
ok
:=
parent
.
files
[
base
]
if
ok
{
return
parent
,
file
}
return
parent
.
subdirs
[
base
],
nil
func
(
me
*
MemTreeFs
)
Root
()
fuse
.
FsNode
{
return
&
me
.
root
}
func
(
me
*
MemTree
)
FindDir
(
name
string
)
*
MemTree
{
s
,
ok
:=
me
.
subdirs
[
name
]
if
!
ok
{
s
=
NewMemTree
()
me
.
subdirs
[
name
]
=
s
func
(
me
*
memNode
)
Print
(
indent
int
)
{
s
:=
""
for
i
:=
0
;
i
<
indent
;
i
++
{
s
=
s
+
" "
}
return
s
}
////////////////////////////////////////////////////////////////
type
MemTreeFileSystem
struct
{
tree
*
MemTree
fuse
.
DefaultFileSystem
}
func
NewMemTreeFileSystem
(
t
*
MemTree
)
*
MemTreeFileSystem
{
return
&
MemTreeFileSystem
{
tree
:
t
,
children
:=
me
.
Inode
()
.
Children
()
for
k
,
v
:=
range
children
{
if
v
.
IsDir
()
{
fmt
.
Println
(
s
+
k
+
":"
)
mn
,
ok
:=
v
.
FsNode
()
.
(
*
memNode
)
if
ok
{
mn
.
Print
(
indent
+
2
)
}
}
else
{
fmt
.
Println
(
s
+
k
)
}
}
}
const
mem_DIRMODE
uint32
=
fuse
.
S_IFDIR
|
0500
const
mem_FILEMODE
uint32
=
fuse
.
S_IFREG
|
0400
func
(
me
*
MemTreeFileSystem
)
Name
()
string
{
return
"MemTreeFileSystem"
}
func
(
me
*
MemTreeFileSystem
)
GetAttr
(
name
string
,
context
*
fuse
.
Context
)
(
*
os
.
FileInfo
,
fuse
.
Status
)
{
dir
,
file
:=
me
.
tree
.
Lookup
(
name
)
if
dir
==
nil
{
return
nil
,
fuse
.
ENOENT
}
a
:=
&
os
.
FileInfo
{}
if
file
==
nil
{
a
.
Mode
=
mem_DIRMODE
}
else
{
a
=
file
.
Stat
()
func
(
me
*
memNode
)
OpenDir
(
context
*
fuse
.
Context
)
(
stream
chan
fuse
.
DirEntry
,
code
fuse
.
Status
)
{
children
:=
me
.
Inode
()
.
Children
()
stream
=
make
(
chan
fuse
.
DirEntry
,
len
(
children
))
for
k
,
v
:=
range
children
{
mode
:=
fuse
.
S_IFREG
|
0666
if
v
.
IsDir
()
{
mode
=
fuse
.
S_IFDIR
|
0777
}
stream
<-
fuse
.
DirEntry
{
Name
:
k
,
Mode
:
uint32
(
mode
),
}
}
return
a
,
fuse
.
OK
close
(
stream
)
return
stream
,
fuse
.
OK
}
func
(
me
*
MemTreeFileSystem
)
Open
(
name
string
,
flags
uint32
,
context
*
fuse
.
Context
)
(
fuseFile
fuse
.
File
,
code
fuse
.
Status
)
{
func
(
me
*
memNode
)
Open
(
flags
uint32
,
context
*
fuse
.
Context
)
(
fuseFile
fuse
.
File
,
code
fuse
.
Status
)
{
if
flags
&
fuse
.
O_ANYWRITE
!=
0
{
return
nil
,
fuse
.
EPERM
}
// TODO - should complain if it is a directory.
_
,
file
:=
me
.
tree
.
Lookup
(
name
)
if
file
==
nil
{
return
nil
,
fuse
.
ENOENT
}
return
fuse
.
NewReadOnlyFile
(
file
.
Data
()),
fuse
.
OK
return
fuse
.
NewReadOnlyFile
(
me
.
file
.
Data
()),
fuse
.
OK
}
func
(
me
*
MemTreeFileSystem
)
OpenDir
(
name
string
,
context
*
fuse
.
Context
)
(
stream
chan
fuse
.
DirEntry
,
code
fuse
.
Status
)
{
dir
,
file
:=
me
.
tree
.
Lookup
(
name
)
if
dir
==
nil
{
return
nil
,
fuse
.
ENOENT
}
if
file
!=
nil
{
return
nil
,
fuse
.
ENOTDIR
func
(
me
*
memNode
)
GetAttr
(
file
fuse
.
File
,
context
*
fuse
.
Context
)
(
*
os
.
FileInfo
,
fuse
.
Status
)
{
if
me
.
Inode
()
.
IsDir
()
{
return
&
os
.
FileInfo
{
Mode
:
fuse
.
S_IFDIR
|
0777
,
},
fuse
.
OK
}
stream
=
make
(
chan
fuse
.
DirEntry
,
len
(
dir
.
files
)
+
len
(
dir
.
subdirs
))
for
k
,
_
:=
range
dir
.
files
{
stream
<-
fuse
.
DirEntry
{
Name
:
k
,
Mode
:
mem_FILEMODE
,
}
}
for
k
,
_
:=
range
dir
.
subdirs
{
stream
<-
fuse
.
DirEntry
{
Name
:
k
,
Mode
:
mem_DIRMODE
,
return
me
.
file
.
Stat
(),
fuse
.
OK
}
func
(
me
*
MemTreeFs
)
addFile
(
name
string
,
f
MemFile
)
{
comps
:=
strings
.
Split
(
name
,
"/"
)
node
:=
me
.
root
.
Inode
()
for
i
,
c
:=
range
comps
{
ch
:=
node
.
GetChild
(
c
)
if
ch
==
nil
{
fsnode
:=
&
memNode
{}
if
i
==
len
(
comps
)
-
1
{
fsnode
.
file
=
f
}
ch
=
node
.
CreateChild
(
c
,
fsnode
.
file
==
nil
,
fsnode
)
}
node
=
ch
}
close
(
stream
)
return
stream
,
fuse
.
OK
}
zipfs/multizip.go
View file @
9ec4c8af
...
...
@@ -32,7 +32,7 @@ const (
type
MultiZipFs
struct
{
Connector
*
fuse
.
FileSystemConnector
lock
sync
.
RWMutex
zips
map
[
string
]
*
MemTreeF
ileSystem
zips
map
[
string
]
*
MemTreeF
s
dirZipFileMap
map
[
string
]
string
fuse
.
DefaultFileSystem
...
...
@@ -40,7 +40,7 @@ type MultiZipFs struct {
func
NewMultiZipFs
()
*
MultiZipFs
{
m
:=
new
(
MultiZipFs
)
m
.
zips
=
make
(
map
[
string
]
*
MemTreeF
ileSystem
)
m
.
zips
=
make
(
map
[
string
]
*
MemTreeF
s
)
m
.
dirZipFileMap
=
make
(
map
[
string
]
string
)
return
m
}
...
...
@@ -171,7 +171,7 @@ func (me *MultiZipFs) Symlink(value string, linkName string, context *fuse.Conte
return
fuse
.
EINVAL
}
code
=
me
.
Connector
.
Mount
(
"/"
+
base
,
f
use
.
NewPathNodeFs
(
fs
)
,
nil
)
code
=
me
.
Connector
.
Mount
(
"/"
+
base
,
f
s
,
nil
)
if
!
code
.
Ok
()
{
return
code
}
...
...
zipfs/multizip_test.go
View file @
9ec4c8af
...
...
@@ -16,7 +16,7 @@ const testTtl = 0.1
func
setupMzfs
()
(
mountPoint
string
,
cleanup
func
())
{
fs
:=
NewMultiZipFs
()
mountPoint
=
fuse
.
MakeTempDir
()
state
,
_
,
err
:=
fuse
.
MountFileSystem
(
mountPoint
,
fs
,
&
fuse
.
FileSystemOptions
{
state
,
_
,
err
:=
fuse
.
Mount
Path
FileSystem
(
mountPoint
,
fs
,
&
fuse
.
FileSystemOptions
{
EntryTimeout
:
testTtl
,
AttrTimeout
:
testTtl
,
NegativeTimeout
:
0.0
,
...
...
zipfs/tarfs.go
View file @
9ec4c8af
...
...
@@ -8,7 +8,6 @@ import (
"fmt"
"io"
"os"
"path/filepath"
"strings"
"syscall"
)
...
...
@@ -45,8 +44,8 @@ func (me *TarFile) Data() []byte {
return
me
.
data
}
func
NewTarTree
(
r
io
.
Reader
)
*
MemTree
{
tree
:=
NewMemTree
()
func
NewTarTree
(
r
io
.
Reader
)
(
map
[
string
]
MemFile
)
{
files
:=
map
[
string
]
MemFile
{}
tr
:=
tar
.
NewReader
(
r
)
var
longName
*
string
...
...
@@ -73,32 +72,22 @@ func NewTarTree(r io.Reader) *MemTree {
longName
=
nil
}
comps
:=
strings
.
Split
(
filepath
.
Clean
(
hdr
.
Name
),
"/"
)
base
:=
""
if
!
strings
.
HasSuffix
(
hdr
.
Name
,
"/"
)
{
base
=
comps
[
len
(
comps
)
-
1
]
comps
=
comps
[
:
len
(
comps
)
-
1
]
}
parent
:=
tree
for
_
,
c
:=
range
comps
{
parent
=
parent
.
FindDir
(
c
)
if
strings
.
HasSuffix
(
hdr
.
Name
,
"/"
)
{
continue
}
buf
:=
bytes
.
NewBuffer
(
make
([]
byte
,
0
,
hdr
.
Size
))
io
.
Copy
(
buf
,
tr
)
if
base
!=
""
{
b
:=
buf
.
Bytes
()
parent
.
files
[
base
]
=
&
TarFile
{
Header
:
*
hdr
,
data
:
b
,
}
files
[
hdr
.
Name
]
=
&
TarFile
{
Header
:
*
hdr
,
data
:
buf
.
Bytes
(),
}
}
return
tree
return
files
}
func
NewTarCompressedTree
(
name
string
,
format
string
)
(
*
MemTre
e
,
os
.
Error
)
{
func
NewTarCompressedTree
(
name
string
,
format
string
)
(
map
[
string
]
MemFil
e
,
os
.
Error
)
{
f
,
err
:=
os
.
Open
(
name
)
if
err
!=
nil
{
return
nil
,
err
...
...
zipfs/zipfs.go
View file @
9ec4c8af
...
...
@@ -4,11 +4,11 @@ import (
"archive/zip"
"bytes"
"fmt"
"github.com/hanwen/go-fuse/fuse"
"io"
"os"
"strings"
"path/filepath"
"s
yscall
"
"s
trings
"
"log"
)
...
...
@@ -21,7 +21,7 @@ type ZipFile struct {
func
(
me
*
ZipFile
)
Stat
()
*
os
.
FileInfo
{
// TODO - do something intelligent with timestamps.
return
&
os
.
FileInfo
{
Mode
:
syscall
.
S_IFREG
|
0444
,
Mode
:
fuse
.
S_IFREG
|
0444
,
Size
:
int64
(
me
.
File
.
UncompressedSize
),
}
}
...
...
@@ -41,62 +41,51 @@ func (me *ZipFile) Data() []byte {
return
dest
.
Bytes
()
}
func
zipFilesToTree
(
files
[]
*
zip
.
File
)
*
MemTree
{
t
:=
NewMemTree
()
for
_
,
f
:=
range
files
{
parent
:=
t
comps
:=
strings
.
Split
(
filepath
.
Clean
(
f
.
Name
),
"/"
)
base
:=
""
// Ugh - zip files have directories separate.
if
!
strings
.
HasSuffix
(
f
.
Name
,
"/"
)
{
base
=
comps
[
len
(
comps
)
-
1
]
comps
=
comps
[
:
len
(
comps
)
-
1
]
}
for
_
,
c
:=
range
comps
{
parent
=
parent
.
FindDir
(
c
)
}
if
base
!=
""
{
parent
.
files
[
base
]
=
&
ZipFile
{
File
:
f
}
}
}
return
t
}
// NewZipTree creates a new file-system for the zip file named name.
func
NewZipTree
(
name
string
)
(
*
MemTre
e
,
os
.
Error
)
{
func
NewZipTree
(
name
string
)
(
map
[
string
]
MemFil
e
,
os
.
Error
)
{
r
,
err
:=
zip
.
OpenReader
(
name
)
if
err
!=
nil
{
return
nil
,
err
}
return
zipFilesToTree
(
r
.
File
),
nil
out
:=
map
[
string
]
MemFile
{}
for
_
,
f
:=
range
r
.
File
{
if
strings
.
HasSuffix
(
f
.
Name
,
"/"
)
{
continue
}
n
:=
filepath
.
Clean
(
f
.
Name
)
zf
:=
&
ZipFile
{
f
}
out
[
n
]
=
zf
}
return
out
,
nil
}
func
NewArchiveFileSystem
(
name
string
)
(
fs
*
MemTreeFileSystem
,
err
os
.
Error
)
{
var
tree
*
MemTree
func
NewArchiveFileSystem
(
name
string
)
(
mfs
*
MemTreeFs
,
err
os
.
Error
)
{
mfs
=
&
MemTreeFs
{}
if
strings
.
HasSuffix
(
name
,
".zip"
)
{
tree
,
err
=
NewZipTree
(
name
)
mfs
.
files
,
err
=
NewZipTree
(
name
)
}
if
strings
.
HasSuffix
(
name
,
".tar.gz"
)
{
tree
,
err
=
NewTarCompressedTree
(
name
,
"gz"
)
mfs
.
files
,
err
=
NewTarCompressedTree
(
name
,
"gz"
)
}
if
strings
.
HasSuffix
(
name
,
".tar.bz2"
)
{
tree
,
err
=
NewTarCompressedTree
(
name
,
"bz2"
)
mfs
.
files
,
err
=
NewTarCompressedTree
(
name
,
"bz2"
)
}
if
strings
.
HasSuffix
(
name
,
".tar"
)
{
f
,
err
:=
os
.
Open
(
name
)
if
err
!=
nil
{
return
nil
,
err
}
tree
=
NewTarTree
(
f
)
mfs
.
files
=
NewTarTree
(
f
)
}
if
err
!=
nil
{
return
nil
,
err
}
if
tree
==
nil
{
if
mfs
.
files
==
nil
{
return
nil
,
os
.
NewError
(
fmt
.
Sprintf
(
"Unknown type for %v"
,
name
))
}
return
NewMemTreeFileSystem
(
tree
)
,
nil
return
mfs
,
nil
}
zipfs/zipfs_test.go
View file @
9ec4c8af
...
...
@@ -24,7 +24,7 @@ func setupZipfs() (mountPoint string, cleanup func()) {
mountPoint
=
fuse
.
MakeTempDir
()
state
,
_
,
err
:=
fuse
.
MountFileSystem
(
mountPoint
,
zfs
,
nil
)
state
,
_
,
err
:=
fuse
.
Mount
Node
FileSystem
(
mountPoint
,
zfs
,
nil
)
state
.
Debug
=
true
go
state
.
Loop
(
false
)
...
...
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