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
5514ae72
Commit
5514ae72
authored
May 02, 2012
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Go style receivers for unionfs/ and zipfs/
parent
7fc85869
Changes
9
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
415 additions
and
415 deletions
+415
-415
unionfs/autounion.go
unionfs/autounion.go
+80
-80
unionfs/cachingfs.go
unionfs/cachingfs.go
+16
-16
unionfs/dircache.go
unionfs/dircache.go
+37
-37
unionfs/timedcache.go
unionfs/timedcache.go
+34
-34
unionfs/unionfs.go
unionfs/unionfs.go
+188
-188
zipfs/memtree.go
zipfs/memtree.go
+19
-19
zipfs/multizip.go
zipfs/multizip.go
+31
-31
zipfs/tarfs.go
zipfs/tarfs.go
+4
-4
zipfs/zipfs.go
zipfs/zipfs.go
+6
-6
No files found.
unionfs/autounion.go
View file @
5514ae72
This diff is collapsed.
Click to expand it.
unionfs/cachingfs.go
View file @
5514ae72
...
...
@@ -107,36 +107,36 @@ func NewCachingFileSystem(fs fuse.FileSystem, ttl time.Duration) *CachingFileSys
return
c
}
func
(
me
*
CachingFileSystem
)
DropCache
()
{
for
_
,
c
:=
range
[]
*
TimedCache
{
me
.
attributes
,
me
.
dirs
,
me
.
links
,
me
.
xattr
}
{
func
(
fs
*
CachingFileSystem
)
DropCache
()
{
for
_
,
c
:=
range
[]
*
TimedCache
{
fs
.
attributes
,
fs
.
dirs
,
fs
.
links
,
fs
.
xattr
}
{
c
.
DropAll
(
nil
)
}
}
func
(
me
*
CachingFileSystem
)
GetAttr
(
name
string
,
context
*
fuse
.
Context
)
(
*
fuse
.
Attr
,
fuse
.
Status
)
{
func
(
fs
*
CachingFileSystem
)
GetAttr
(
name
string
,
context
*
fuse
.
Context
)
(
*
fuse
.
Attr
,
fuse
.
Status
)
{
if
name
==
_DROP_CACHE
{
return
&
fuse
.
Attr
{
Mode
:
fuse
.
S_IFREG
|
0777
,
},
fuse
.
OK
}
r
:=
me
.
attributes
.
Get
(
name
)
.
(
*
attrResponse
)
r
:=
fs
.
attributes
.
Get
(
name
)
.
(
*
attrResponse
)
return
r
.
Attr
,
r
.
Status
}
func
(
me
*
CachingFileSystem
)
GetXAttr
(
name
string
,
attr
string
,
context
*
fuse
.
Context
)
([]
byte
,
fuse
.
Status
)
{
func
(
fs
*
CachingFileSystem
)
GetXAttr
(
name
string
,
attr
string
,
context
*
fuse
.
Context
)
([]
byte
,
fuse
.
Status
)
{
key
:=
name
+
_XATTRSEP
+
attr
r
:=
me
.
xattr
.
Get
(
key
)
.
(
*
xattrResponse
)
r
:=
fs
.
xattr
.
Get
(
key
)
.
(
*
xattrResponse
)
return
r
.
data
,
r
.
Status
}
func
(
me
*
CachingFileSystem
)
Readlink
(
name
string
,
context
*
fuse
.
Context
)
(
string
,
fuse
.
Status
)
{
r
:=
me
.
links
.
Get
(
name
)
.
(
*
linkResponse
)
func
(
fs
*
CachingFileSystem
)
Readlink
(
name
string
,
context
*
fuse
.
Context
)
(
string
,
fuse
.
Status
)
{
r
:=
fs
.
links
.
Get
(
name
)
.
(
*
linkResponse
)
return
r
.
linkContent
,
r
.
Status
}
func
(
me
*
CachingFileSystem
)
OpenDir
(
name
string
,
context
*
fuse
.
Context
)
(
stream
chan
fuse
.
DirEntry
,
status
fuse
.
Status
)
{
r
:=
me
.
dirs
.
Get
(
name
)
.
(
*
dirResponse
)
func
(
fs
*
CachingFileSystem
)
OpenDir
(
name
string
,
context
*
fuse
.
Context
)
(
stream
chan
fuse
.
DirEntry
,
status
fuse
.
Status
)
{
r
:=
fs
.
dirs
.
Get
(
name
)
.
(
*
dirResponse
)
if
r
.
Status
.
Ok
()
{
stream
=
make
(
chan
fuse
.
DirEntry
,
len
(
r
.
entries
))
for
_
,
d
:=
range
r
.
entries
{
...
...
@@ -149,14 +149,14 @@ func (me *CachingFileSystem) OpenDir(name string, context *fuse.Context) (stream
return
nil
,
r
.
Status
}
func
(
me
*
CachingFileSystem
)
String
()
string
{
return
fmt
.
Sprintf
(
"CachingFileSystem(%v)"
,
me
.
FileSystem
)
func
(
fs
*
CachingFileSystem
)
String
()
string
{
return
fmt
.
Sprintf
(
"CachingFileSystem(%v)"
,
fs
.
FileSystem
)
}
func
(
me
*
CachingFileSystem
)
Open
(
name
string
,
flags
uint32
,
context
*
fuse
.
Context
)
(
f
fuse
.
File
,
status
fuse
.
Status
)
{
func
(
fs
*
CachingFileSystem
)
Open
(
name
string
,
flags
uint32
,
context
*
fuse
.
Context
)
(
f
fuse
.
File
,
status
fuse
.
Status
)
{
if
flags
&
fuse
.
O_ANYWRITE
!=
0
&&
name
==
_DROP_CACHE
{
log
.
Println
(
"Dropping cache for"
,
me
)
me
.
DropCache
()
log
.
Println
(
"Dropping cache for"
,
fs
)
fs
.
DropCache
()
}
return
me
.
FileSystem
.
Open
(
name
,
flags
,
context
)
return
fs
.
FileSystem
.
Open
(
name
,
flags
,
context
)
}
unionfs/dircache.go
View file @
5514ae72
...
...
@@ -42,57 +42,57 @@ type DirCache struct {
updateRunning
bool
}
func
(
me
*
DirCache
)
setMap
(
newMap
map
[
string
]
bool
)
{
me
.
lock
.
Lock
()
defer
me
.
lock
.
Unlock
()
me
.
names
=
newMap
me
.
updateRunning
=
false
_
=
time
.
AfterFunc
(
me
.
ttl
,
func
()
{
me
.
DropCache
()
})
func
(
c
*
DirCache
)
setMap
(
newMap
map
[
string
]
bool
)
{
c
.
lock
.
Lock
()
defer
c
.
lock
.
Unlock
()
c
.
names
=
newMap
c
.
updateRunning
=
false
_
=
time
.
AfterFunc
(
c
.
ttl
,
func
()
{
c
.
DropCache
()
})
}
func
(
me
*
DirCache
)
DropCache
()
{
me
.
lock
.
Lock
()
defer
me
.
lock
.
Unlock
()
me
.
names
=
nil
func
(
c
*
DirCache
)
DropCache
()
{
c
.
lock
.
Lock
()
defer
c
.
lock
.
Unlock
()
c
.
names
=
nil
}
// Try to refresh: if another update is already running, do nothing,
// otherwise, read the directory and set it.
func
(
me
*
DirCache
)
maybeRefresh
()
{
me
.
lock
.
Lock
()
defer
me
.
lock
.
Unlock
()
if
me
.
updateRunning
{
func
(
c
*
DirCache
)
maybeRefresh
()
{
c
.
lock
.
Lock
()
defer
c
.
lock
.
Unlock
()
if
c
.
updateRunning
{
return
}
me
.
updateRunning
=
true
c
.
updateRunning
=
true
go
func
()
{
newmap
:=
newDirnameMap
(
me
.
fs
,
me
.
dir
)
me
.
setMap
(
newmap
)
newmap
:=
newDirnameMap
(
c
.
fs
,
c
.
dir
)
c
.
setMap
(
newmap
)
}()
}
func
(
me
*
DirCache
)
RemoveEntry
(
name
string
)
{
me
.
lock
.
Lock
()
defer
me
.
lock
.
Unlock
()
if
me
.
names
==
nil
{
go
me
.
maybeRefresh
()
func
(
c
*
DirCache
)
RemoveEntry
(
name
string
)
{
c
.
lock
.
Lock
()
defer
c
.
lock
.
Unlock
()
if
c
.
names
==
nil
{
go
c
.
maybeRefresh
()
return
}
delete
(
me
.
names
,
name
)
delete
(
c
.
names
,
name
)
}
func
(
me
*
DirCache
)
AddEntry
(
name
string
)
{
me
.
lock
.
Lock
()
defer
me
.
lock
.
Unlock
()
if
me
.
names
==
nil
{
go
me
.
maybeRefresh
()
func
(
c
*
DirCache
)
AddEntry
(
name
string
)
{
c
.
lock
.
Lock
()
defer
c
.
lock
.
Unlock
()
if
c
.
names
==
nil
{
go
c
.
maybeRefresh
()
return
}
me
.
names
[
name
]
=
true
c
.
names
[
name
]
=
true
}
func
NewDirCache
(
fs
fuse
.
FileSystem
,
dir
string
,
ttl
time
.
Duration
)
*
DirCache
{
...
...
@@ -103,14 +103,14 @@ func NewDirCache(fs fuse.FileSystem, dir string, ttl time.Duration) *DirCache {
return
dc
}
func
(
me
*
DirCache
)
HasEntry
(
name
string
)
(
mapPresent
bool
,
found
bool
)
{
me
.
lock
.
RLock
()
defer
me
.
lock
.
RUnlock
()
func
(
c
*
DirCache
)
HasEntry
(
name
string
)
(
mapPresent
bool
,
found
bool
)
{
c
.
lock
.
RLock
()
defer
c
.
lock
.
RUnlock
()
if
me
.
names
==
nil
{
go
me
.
maybeRefresh
()
if
c
.
names
==
nil
{
go
c
.
maybeRefresh
()
return
false
,
false
}
return
true
,
me
.
names
[
name
]
return
true
,
c
.
names
[
name
]
}
unionfs/timedcache.go
View file @
5514ae72
...
...
@@ -42,79 +42,79 @@ func NewTimedCache(fetcher TimedCacheFetcher, ttl time.Duration) *TimedCache {
return
l
}
func
(
me
*
TimedCache
)
Get
(
name
string
)
interface
{}
{
me
.
cacheMapMutex
.
RLock
()
info
,
ok
:=
me
.
cacheMap
[
name
]
me
.
cacheMapMutex
.
RUnlock
()
func
(
c
*
TimedCache
)
Get
(
name
string
)
interface
{}
{
c
.
cacheMapMutex
.
RLock
()
info
,
ok
:=
c
.
cacheMap
[
name
]
c
.
cacheMapMutex
.
RUnlock
()
valid
:=
ok
&&
(
me
.
ttl
<=
0
||
info
.
expiry
.
After
(
time
.
Now
()))
valid
:=
ok
&&
(
c
.
ttl
<=
0
||
info
.
expiry
.
After
(
time
.
Now
()))
if
valid
{
return
info
.
data
}
return
me
.
GetFresh
(
name
)
return
c
.
GetFresh
(
name
)
}
func
(
me
*
TimedCache
)
Set
(
name
string
,
val
interface
{})
{
me
.
cacheMapMutex
.
Lock
()
defer
me
.
cacheMapMutex
.
Unlock
()
func
(
c
*
TimedCache
)
Set
(
name
string
,
val
interface
{})
{
c
.
cacheMapMutex
.
Lock
()
defer
c
.
cacheMapMutex
.
Unlock
()
me
.
cacheMap
[
name
]
=
&
cacheEntry
{
c
.
cacheMap
[
name
]
=
&
cacheEntry
{
data
:
val
,
expiry
:
time
.
Now
()
.
Add
(
me
.
ttl
),
expiry
:
time
.
Now
()
.
Add
(
c
.
ttl
),
}
}
func
(
me
*
TimedCache
)
DropEntry
(
name
string
)
{
me
.
cacheMapMutex
.
Lock
()
defer
me
.
cacheMapMutex
.
Unlock
()
func
(
c
*
TimedCache
)
DropEntry
(
name
string
)
{
c
.
cacheMapMutex
.
Lock
()
defer
c
.
cacheMapMutex
.
Unlock
()
delete
(
me
.
cacheMap
,
name
)
delete
(
c
.
cacheMap
,
name
)
}
func
(
me
*
TimedCache
)
GetFresh
(
name
string
)
interface
{}
{
data
,
ok
:=
me
.
fetch
(
name
)
func
(
c
*
TimedCache
)
GetFresh
(
name
string
)
interface
{}
{
data
,
ok
:=
c
.
fetch
(
name
)
if
ok
{
me
.
Set
(
name
,
data
)
c
.
Set
(
name
,
data
)
}
return
data
}
// Drop all expired entries.
func
(
me
*
TimedCache
)
Purge
()
{
keys
:=
make
([]
string
,
0
,
len
(
me
.
cacheMap
))
func
(
c
*
TimedCache
)
Purge
()
{
keys
:=
make
([]
string
,
0
,
len
(
c
.
cacheMap
))
now
:=
time
.
Now
()
me
.
cacheMapMutex
.
Lock
()
defer
me
.
cacheMapMutex
.
Unlock
()
for
k
,
v
:=
range
me
.
cacheMap
{
c
.
cacheMapMutex
.
Lock
()
defer
c
.
cacheMapMutex
.
Unlock
()
for
k
,
v
:=
range
c
.
cacheMap
{
if
now
.
After
(
v
.
expiry
)
{
keys
=
append
(
keys
,
k
)
}
}
for
_
,
k
:=
range
keys
{
delete
(
me
.
cacheMap
,
k
)
delete
(
c
.
cacheMap
,
k
)
}
}
func
(
me
*
TimedCache
)
RecurringPurge
()
{
if
me
.
ttl
<=
0
{
func
(
c
*
TimedCache
)
RecurringPurge
()
{
if
c
.
ttl
<=
0
{
return
}
me
.
Purge
()
me
.
PurgeTimer
=
time
.
AfterFunc
(
me
.
ttl
*
5
,
func
()
{
me
.
RecurringPurge
()
})
c
.
Purge
()
c
.
PurgeTimer
=
time
.
AfterFunc
(
c
.
ttl
*
5
,
func
()
{
c
.
RecurringPurge
()
})
}
func
(
me
*
TimedCache
)
DropAll
(
names
[]
string
)
{
me
.
cacheMapMutex
.
Lock
()
defer
me
.
cacheMapMutex
.
Unlock
()
func
(
c
*
TimedCache
)
DropAll
(
names
[]
string
)
{
c
.
cacheMapMutex
.
Lock
()
defer
c
.
cacheMapMutex
.
Unlock
()
if
names
==
nil
{
me
.
cacheMap
=
make
(
map
[
string
]
*
cacheEntry
,
len
(
me
.
cacheMap
))
c
.
cacheMap
=
make
(
map
[
string
]
*
cacheEntry
,
len
(
c
.
cacheMap
))
}
else
{
for
_
,
nm
:=
range
names
{
delete
(
me
.
cacheMap
,
nm
)
delete
(
c
.
cacheMap
,
nm
)
}
}
}
unionfs/unionfs.go
View file @
5514ae72
This diff is collapsed.
Click to expand it.
zipfs/memtree.go
View file @
5514ae72
...
...
@@ -30,24 +30,24 @@ func NewMemTreeFs() *MemTreeFs {
return
d
}
func
(
me
*
MemTreeFs
)
OnMount
(
conn
*
fuse
.
FileSystemConnector
)
{
for
k
,
v
:=
range
me
.
files
{
me
.
addFile
(
k
,
v
)
func
(
fs
*
MemTreeFs
)
OnMount
(
conn
*
fuse
.
FileSystemConnector
)
{
for
k
,
v
:=
range
fs
.
files
{
fs
.
addFile
(
k
,
v
)
}
me
.
files
=
nil
fs
.
files
=
nil
}
func
(
me
*
MemTreeFs
)
Root
()
fuse
.
FsNode
{
return
&
me
.
root
func
(
fs
*
MemTreeFs
)
Root
()
fuse
.
FsNode
{
return
&
fs
.
root
}
func
(
me
*
memNode
)
Print
(
indent
int
)
{
func
(
n
*
memNode
)
Print
(
indent
int
)
{
s
:=
""
for
i
:=
0
;
i
<
indent
;
i
++
{
s
=
s
+
" "
}
children
:=
me
.
Inode
()
.
Children
()
children
:=
n
.
Inode
()
.
Children
()
for
k
,
v
:=
range
children
{
if
v
.
IsDir
()
{
fmt
.
Println
(
s
+
k
+
":"
)
...
...
@@ -62,12 +62,12 @@ func (me *memNode) Print(indent int) {
}
// We construct the tree at mount, so we never need to look anything up.
func
(
me
*
memNode
)
Lookup
(
name
string
,
c
*
fuse
.
Context
)
(
fi
*
fuse
.
Attr
,
node
fuse
.
FsNode
,
code
fuse
.
Status
)
{
func
(
n
*
memNode
)
Lookup
(
name
string
,
c
*
fuse
.
Context
)
(
fi
*
fuse
.
Attr
,
node
fuse
.
FsNode
,
code
fuse
.
Status
)
{
return
nil
,
nil
,
fuse
.
ENOENT
}
func
(
me
*
memNode
)
OpenDir
(
context
*
fuse
.
Context
)
(
stream
chan
fuse
.
DirEntry
,
code
fuse
.
Status
)
{
children
:=
me
.
Inode
()
.
Children
()
func
(
n
*
memNode
)
OpenDir
(
context
*
fuse
.
Context
)
(
stream
chan
fuse
.
DirEntry
,
code
fuse
.
Status
)
{
children
:=
n
.
Inode
()
.
Children
()
stream
=
make
(
chan
fuse
.
DirEntry
,
len
(
children
))
for
k
,
v
:=
range
children
{
mode
:=
fuse
.
S_IFREG
|
0666
...
...
@@ -83,32 +83,32 @@ func (me *memNode) OpenDir(context *fuse.Context) (stream chan fuse.DirEntry, co
return
stream
,
fuse
.
OK
}
func
(
me
*
memNode
)
Open
(
flags
uint32
,
context
*
fuse
.
Context
)
(
fuseFile
fuse
.
File
,
code
fuse
.
Status
)
{
func
(
n
*
memNode
)
Open
(
flags
uint32
,
context
*
fuse
.
Context
)
(
fuseFile
fuse
.
File
,
code
fuse
.
Status
)
{
if
flags
&
fuse
.
O_ANYWRITE
!=
0
{
return
nil
,
fuse
.
EPERM
}
return
fuse
.
NewDataFile
(
me
.
file
.
Data
()),
fuse
.
OK
return
fuse
.
NewDataFile
(
n
.
file
.
Data
()),
fuse
.
OK
}
func
(
me
*
memNode
)
Deletable
()
bool
{
func
(
n
*
memNode
)
Deletable
()
bool
{
return
false
}
func
(
me
*
memNode
)
GetAttr
(
file
fuse
.
File
,
context
*
fuse
.
Context
)
(
*
fuse
.
Attr
,
fuse
.
Status
)
{
if
me
.
Inode
()
.
IsDir
()
{
func
(
n
*
memNode
)
GetAttr
(
file
fuse
.
File
,
context
*
fuse
.
Context
)
(
*
fuse
.
Attr
,
fuse
.
Status
)
{
if
n
.
Inode
()
.
IsDir
()
{
return
&
fuse
.
Attr
{
Mode
:
fuse
.
S_IFDIR
|
0777
,
},
fuse
.
OK
}
return
me
.
file
.
Stat
(),
fuse
.
OK
return
n
.
file
.
Stat
(),
fuse
.
OK
}
func
(
me
*
MemTreeFs
)
addFile
(
name
string
,
f
MemFile
)
{
func
(
n
*
MemTreeFs
)
addFile
(
name
string
,
f
MemFile
)
{
comps
:=
strings
.
Split
(
name
,
"/"
)
node
:=
me
.
root
.
Inode
()
node
:=
n
.
root
.
Inode
()
for
i
,
c
:=
range
comps
{
child
:=
node
.
GetChild
(
c
)
if
child
==
nil
{
...
...
zipfs/multizip.go
View file @
5514ae72
...
...
@@ -42,19 +42,19 @@ func NewMultiZipFs() *MultiZipFs {
return
m
}
func
(
me
*
MultiZipFs
)
String
()
string
{
func
(
fs
*
MultiZipFs
)
String
()
string
{
return
"MultiZipFs"
}
func
(
me
*
MultiZipFs
)
OnMount
(
nodeFs
*
fuse
.
PathNodeFs
)
{
me
.
nodeFs
=
nodeFs
func
(
fs
*
MultiZipFs
)
OnMount
(
nodeFs
*
fuse
.
PathNodeFs
)
{
fs
.
nodeFs
=
nodeFs
}
func
(
me
*
MultiZipFs
)
OpenDir
(
name
string
,
context
*
fuse
.
Context
)
(
stream
chan
fuse
.
DirEntry
,
code
fuse
.
Status
)
{
me
.
lock
.
RLock
()
defer
me
.
lock
.
RUnlock
()
func
(
fs
*
MultiZipFs
)
OpenDir
(
name
string
,
context
*
fuse
.
Context
)
(
stream
chan
fuse
.
DirEntry
,
code
fuse
.
Status
)
{
fs
.
lock
.
RLock
()
defer
fs
.
lock
.
RUnlock
()
stream
=
make
(
chan
fuse
.
DirEntry
,
len
(
me
.
zips
)
+
2
)
stream
=
make
(
chan
fuse
.
DirEntry
,
len
(
fs
.
zips
)
+
2
)
if
name
==
""
{
var
d
fuse
.
DirEntry
d
.
Name
=
"config"
...
...
@@ -63,7 +63,7 @@ func (me *MultiZipFs) OpenDir(name string, context *fuse.Context) (stream chan f
}
if
name
==
"config"
{
for
k
:=
range
me
.
zips
{
for
k
:=
range
fs
.
zips
{
var
d
fuse
.
DirEntry
d
.
Name
=
k
d
.
Mode
=
fuse
.
S_IFLNK
...
...
@@ -75,7 +75,7 @@ func (me *MultiZipFs) OpenDir(name string, context *fuse.Context) (stream chan f
return
stream
,
fuse
.
OK
}
func
(
me
*
MultiZipFs
)
GetAttr
(
name
string
,
context
*
fuse
.
Context
)
(
*
fuse
.
Attr
,
fuse
.
Status
)
{
func
(
fs
*
MultiZipFs
)
GetAttr
(
name
string
,
context
*
fuse
.
Context
)
(
*
fuse
.
Attr
,
fuse
.
Status
)
{
a
:=
&
fuse
.
Attr
{}
if
name
==
""
{
// Should not write in top dir.
...
...
@@ -97,11 +97,11 @@ func (me *MultiZipFs) GetAttr(name string, context *fuse.Context) (*fuse.Attr, f
submode
=
fuse
.
S_IFLNK
|
0600
}
me
.
lock
.
RLock
()
defer
me
.
lock
.
RUnlock
()
fs
.
lock
.
RLock
()
defer
fs
.
lock
.
RUnlock
()
a
.
Mode
=
submode
_
,
hasDir
:=
me
.
zips
[
base
]
_
,
hasDir
:=
fs
.
zips
[
base
]
if
hasDir
{
return
a
,
fuse
.
OK
}
...
...
@@ -109,20 +109,20 @@ func (me *MultiZipFs) GetAttr(name string, context *fuse.Context) (*fuse.Attr, f
return
nil
,
fuse
.
ENOENT
}
func
(
me
*
MultiZipFs
)
Unlink
(
name
string
,
context
*
fuse
.
Context
)
(
code
fuse
.
Status
)
{
func
(
fs
*
MultiZipFs
)
Unlink
(
name
string
,
context
*
fuse
.
Context
)
(
code
fuse
.
Status
)
{
dir
,
basename
:=
filepath
.
Split
(
name
)
if
dir
==
CONFIG_PREFIX
{
me
.
lock
.
Lock
()
defer
me
.
lock
.
Unlock
()
fs
.
lock
.
Lock
()
defer
fs
.
lock
.
Unlock
()
zfs
,
ok
:=
me
.
zips
[
basename
]
zfs
,
ok
:=
fs
.
zips
[
basename
]
if
ok
{
code
=
me
.
nodeFs
.
UnmountNode
(
zfs
.
Root
()
.
Inode
())
code
=
fs
.
nodeFs
.
UnmountNode
(
zfs
.
Root
()
.
Inode
())
if
!
code
.
Ok
()
{
return
code
}
delete
(
me
.
zips
,
basename
)
delete
(
me
.
dirZipFileMap
,
basename
)
delete
(
fs
.
zips
,
basename
)
delete
(
fs
.
dirZipFileMap
,
basename
)
return
fuse
.
OK
}
else
{
return
fuse
.
ENOENT
...
...
@@ -131,48 +131,48 @@ func (me *MultiZipFs) Unlink(name string, context *fuse.Context) (code fuse.Stat
return
fuse
.
EPERM
}
func
(
me
*
MultiZipFs
)
Readlink
(
path
string
,
context
*
fuse
.
Context
)
(
val
string
,
code
fuse
.
Status
)
{
func
(
fs
*
MultiZipFs
)
Readlink
(
path
string
,
context
*
fuse
.
Context
)
(
val
string
,
code
fuse
.
Status
)
{
dir
,
base
:=
filepath
.
Split
(
path
)
if
dir
!=
CONFIG_PREFIX
{
return
""
,
fuse
.
ENOENT
}
me
.
lock
.
Lock
()
defer
me
.
lock
.
Unlock
()
fs
.
lock
.
Lock
()
defer
fs
.
lock
.
Unlock
()
zipfile
,
ok
:=
me
.
dirZipFileMap
[
base
]
zipfile
,
ok
:=
fs
.
dirZipFileMap
[
base
]
if
!
ok
{
return
""
,
fuse
.
ENOENT
}
return
zipfile
,
fuse
.
OK
}
func
(
me
*
MultiZipFs
)
Symlink
(
value
string
,
linkName
string
,
context
*
fuse
.
Context
)
(
code
fuse
.
Status
)
{
func
(
fs
*
MultiZipFs
)
Symlink
(
value
string
,
linkName
string
,
context
*
fuse
.
Context
)
(
code
fuse
.
Status
)
{
dir
,
base
:=
filepath
.
Split
(
linkName
)
if
dir
!=
CONFIG_PREFIX
{
return
fuse
.
EPERM
}
me
.
lock
.
Lock
()
defer
me
.
lock
.
Unlock
()
fs
.
lock
.
Lock
()
defer
fs
.
lock
.
Unlock
()
_
,
ok
:=
me
.
dirZipFileMap
[
base
]
_
,
ok
:=
fs
.
dirZipFileMap
[
base
]
if
ok
{
return
fuse
.
EBUSY
}
fs
,
err
:=
NewArchiveFileSystem
(
value
)
a
fs
,
err
:=
NewArchiveFileSystem
(
value
)
if
err
!=
nil
{
log
.
Println
(
"NewZipArchiveFileSystem failed."
,
err
)
return
fuse
.
EINVAL
}
code
=
me
.
nodeFs
.
Mount
(
base
,
fs
,
nil
)
code
=
fs
.
nodeFs
.
Mount
(
base
,
a
fs
,
nil
)
if
!
code
.
Ok
()
{
return
code
}
me
.
dirZipFileMap
[
base
]
=
value
me
.
zips
[
base
]
=
fs
fs
.
dirZipFileMap
[
base
]
=
value
fs
.
zips
[
base
]
=
a
fs
return
fuse
.
OK
}
zipfs/tarfs.go
View file @
5514ae72
...
...
@@ -33,14 +33,14 @@ type TarFile struct {
tar
.
Header
}
func
(
me
*
TarFile
)
Stat
()
*
fuse
.
Attr
{
fi
,
_
:=
HeaderToFileInfo
(
&
me
.
Header
)
func
(
f
*
TarFile
)
Stat
()
*
fuse
.
Attr
{
fi
,
_
:=
HeaderToFileInfo
(
&
f
.
Header
)
fi
.
Mode
|=
syscall
.
S_IFREG
return
fi
}
func
(
me
*
TarFile
)
Data
()
[]
byte
{
return
me
.
data
func
(
f
*
TarFile
)
Data
()
[]
byte
{
return
f
.
data
}
func
NewTarTree
(
r
io
.
Reader
)
map
[
string
]
MemFile
{
...
...
zipfs/zipfs.go
View file @
5514ae72
...
...
@@ -19,23 +19,23 @@ type ZipFile struct {
*
zip
.
File
}
func
(
me
*
ZipFile
)
Stat
()
*
fuse
.
Attr
{
func
(
f
*
ZipFile
)
Stat
()
*
fuse
.
Attr
{
// TODO - do something intelligent with timestamps.
return
&
fuse
.
Attr
{
Mode
:
fuse
.
S_IFREG
|
0444
,
Size
:
uint64
(
me
.
File
.
UncompressedSize
),
Size
:
uint64
(
f
.
File
.
UncompressedSize
),
}
}
func
(
me
*
ZipFile
)
Data
()
[]
byte
{
zf
:=
(
*
me
)
func
(
f
*
ZipFile
)
Data
()
[]
byte
{
zf
:=
(
*
f
)
rc
,
err
:=
zf
.
Open
()
if
err
!=
nil
{
panic
(
err
)
}
dest
:=
bytes
.
NewBuffer
(
make
([]
byte
,
0
,
me
.
UncompressedSize
))
dest
:=
bytes
.
NewBuffer
(
make
([]
byte
,
0
,
f
.
UncompressedSize
))
_
,
err
=
io
.
CopyN
(
dest
,
rc
,
int64
(
me
.
UncompressedSize
))
_
,
err
=
io
.
CopyN
(
dest
,
rc
,
int64
(
f
.
UncompressedSize
))
if
err
!=
nil
{
panic
(
err
)
}
...
...
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