Commit 5514ae72 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Go style receivers for unionfs/ and zipfs/

parent 7fc85869
This diff is collapsed.
...@@ -107,36 +107,36 @@ func NewCachingFileSystem(fs fuse.FileSystem, ttl time.Duration) *CachingFileSys ...@@ -107,36 +107,36 @@ func NewCachingFileSystem(fs fuse.FileSystem, ttl time.Duration) *CachingFileSys
return c return c
} }
func (me *CachingFileSystem) DropCache() { func (fs *CachingFileSystem) DropCache() {
for _, c := range []*TimedCache{me.attributes, me.dirs, me.links, me.xattr} { for _, c := range []*TimedCache{fs.attributes, fs.dirs, fs.links, fs.xattr} {
c.DropAll(nil) 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 { if name == _DROP_CACHE {
return &fuse.Attr{ return &fuse.Attr{
Mode: fuse.S_IFREG | 0777, Mode: fuse.S_IFREG | 0777,
}, fuse.OK }, fuse.OK
} }
r := me.attributes.Get(name).(*attrResponse) r := fs.attributes.Get(name).(*attrResponse)
return r.Attr, r.Status 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 key := name + _XATTRSEP + attr
r := me.xattr.Get(key).(*xattrResponse) r := fs.xattr.Get(key).(*xattrResponse)
return r.data, r.Status return r.data, r.Status
} }
func (me *CachingFileSystem) Readlink(name string, context *fuse.Context) (string, fuse.Status) { func (fs *CachingFileSystem) Readlink(name string, context *fuse.Context) (string, fuse.Status) {
r := me.links.Get(name).(*linkResponse) r := fs.links.Get(name).(*linkResponse)
return r.linkContent, r.Status return r.linkContent, r.Status
} }
func (me *CachingFileSystem) OpenDir(name string, context *fuse.Context) (stream chan fuse.DirEntry, status fuse.Status) { func (fs *CachingFileSystem) OpenDir(name string, context *fuse.Context) (stream chan fuse.DirEntry, status fuse.Status) {
r := me.dirs.Get(name).(*dirResponse) r := fs.dirs.Get(name).(*dirResponse)
if r.Status.Ok() { if r.Status.Ok() {
stream = make(chan fuse.DirEntry, len(r.entries)) stream = make(chan fuse.DirEntry, len(r.entries))
for _, d := range r.entries { for _, d := range r.entries {
...@@ -149,14 +149,14 @@ func (me *CachingFileSystem) OpenDir(name string, context *fuse.Context) (stream ...@@ -149,14 +149,14 @@ func (me *CachingFileSystem) OpenDir(name string, context *fuse.Context) (stream
return nil, r.Status return nil, r.Status
} }
func (me *CachingFileSystem) String() string { func (fs *CachingFileSystem) String() string {
return fmt.Sprintf("CachingFileSystem(%v)", me.FileSystem) 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 { if flags&fuse.O_ANYWRITE != 0 && name == _DROP_CACHE {
log.Println("Dropping cache for", me) log.Println("Dropping cache for", fs)
me.DropCache() fs.DropCache()
} }
return me.FileSystem.Open(name, flags, context) return fs.FileSystem.Open(name, flags, context)
} }
...@@ -42,57 +42,57 @@ type DirCache struct { ...@@ -42,57 +42,57 @@ type DirCache struct {
updateRunning bool updateRunning bool
} }
func (me *DirCache) setMap(newMap map[string]bool) { func (c *DirCache) setMap(newMap map[string]bool) {
me.lock.Lock() c.lock.Lock()
defer me.lock.Unlock() defer c.lock.Unlock()
me.names = newMap c.names = newMap
me.updateRunning = false c.updateRunning = false
_ = time.AfterFunc(me.ttl, _ = time.AfterFunc(c.ttl,
func() { me.DropCache() }) func() { c.DropCache() })
} }
func (me *DirCache) DropCache() { func (c *DirCache) DropCache() {
me.lock.Lock() c.lock.Lock()
defer me.lock.Unlock() defer c.lock.Unlock()
me.names = nil c.names = nil
} }
// Try to refresh: if another update is already running, do nothing, // Try to refresh: if another update is already running, do nothing,
// otherwise, read the directory and set it. // otherwise, read the directory and set it.
func (me *DirCache) maybeRefresh() { func (c *DirCache) maybeRefresh() {
me.lock.Lock() c.lock.Lock()
defer me.lock.Unlock() defer c.lock.Unlock()
if me.updateRunning { if c.updateRunning {
return return
} }
me.updateRunning = true c.updateRunning = true
go func() { go func() {
newmap := newDirnameMap(me.fs, me.dir) newmap := newDirnameMap(c.fs, c.dir)
me.setMap(newmap) c.setMap(newmap)
}() }()
} }
func (me *DirCache) RemoveEntry(name string) { func (c *DirCache) RemoveEntry(name string) {
me.lock.Lock() c.lock.Lock()
defer me.lock.Unlock() defer c.lock.Unlock()
if me.names == nil { if c.names == nil {
go me.maybeRefresh() go c.maybeRefresh()
return return
} }
delete(me.names, name) delete(c.names, name)
} }
func (me *DirCache) AddEntry(name string) { func (c *DirCache) AddEntry(name string) {
me.lock.Lock() c.lock.Lock()
defer me.lock.Unlock() defer c.lock.Unlock()
if me.names == nil { if c.names == nil {
go me.maybeRefresh() go c.maybeRefresh()
return return
} }
me.names[name] = true c.names[name] = true
} }
func NewDirCache(fs fuse.FileSystem, dir string, ttl time.Duration) *DirCache { 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 { ...@@ -103,14 +103,14 @@ func NewDirCache(fs fuse.FileSystem, dir string, ttl time.Duration) *DirCache {
return dc return dc
} }
func (me *DirCache) HasEntry(name string) (mapPresent bool, found bool) { func (c *DirCache) HasEntry(name string) (mapPresent bool, found bool) {
me.lock.RLock() c.lock.RLock()
defer me.lock.RUnlock() defer c.lock.RUnlock()
if me.names == nil { if c.names == nil {
go me.maybeRefresh() go c.maybeRefresh()
return false, false return false, false
} }
return true, me.names[name] return true, c.names[name]
} }
...@@ -42,79 +42,79 @@ func NewTimedCache(fetcher TimedCacheFetcher, ttl time.Duration) *TimedCache { ...@@ -42,79 +42,79 @@ func NewTimedCache(fetcher TimedCacheFetcher, ttl time.Duration) *TimedCache {
return l return l
} }
func (me *TimedCache) Get(name string) interface{} { func (c *TimedCache) Get(name string) interface{} {
me.cacheMapMutex.RLock() c.cacheMapMutex.RLock()
info, ok := me.cacheMap[name] info, ok := c.cacheMap[name]
me.cacheMapMutex.RUnlock() 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 { if valid {
return info.data return info.data
} }
return me.GetFresh(name) return c.GetFresh(name)
} }
func (me *TimedCache) Set(name string, val interface{}) { func (c *TimedCache) Set(name string, val interface{}) {
me.cacheMapMutex.Lock() c.cacheMapMutex.Lock()
defer me.cacheMapMutex.Unlock() defer c.cacheMapMutex.Unlock()
me.cacheMap[name] = &cacheEntry{ c.cacheMap[name] = &cacheEntry{
data: val, data: val,
expiry: time.Now().Add(me.ttl), expiry: time.Now().Add(c.ttl),
} }
} }
func (me *TimedCache) DropEntry(name string) { func (c *TimedCache) DropEntry(name string) {
me.cacheMapMutex.Lock() c.cacheMapMutex.Lock()
defer me.cacheMapMutex.Unlock() defer c.cacheMapMutex.Unlock()
delete(me.cacheMap, name) delete(c.cacheMap, name)
} }
func (me *TimedCache) GetFresh(name string) interface{} { func (c *TimedCache) GetFresh(name string) interface{} {
data, ok := me.fetch(name) data, ok := c.fetch(name)
if ok { if ok {
me.Set(name, data) c.Set(name, data)
} }
return data return data
} }
// Drop all expired entries. // Drop all expired entries.
func (me *TimedCache) Purge() { func (c *TimedCache) Purge() {
keys := make([]string, 0, len(me.cacheMap)) keys := make([]string, 0, len(c.cacheMap))
now := time.Now() now := time.Now()
me.cacheMapMutex.Lock() c.cacheMapMutex.Lock()
defer me.cacheMapMutex.Unlock() defer c.cacheMapMutex.Unlock()
for k, v := range me.cacheMap { for k, v := range c.cacheMap {
if now.After(v.expiry) { if now.After(v.expiry) {
keys = append(keys, k) keys = append(keys, k)
} }
} }
for _, k := range keys { for _, k := range keys {
delete(me.cacheMap, k) delete(c.cacheMap, k)
} }
} }
func (me *TimedCache) RecurringPurge() { func (c *TimedCache) RecurringPurge() {
if me.ttl <= 0 { if c.ttl <= 0 {
return return
} }
me.Purge() c.Purge()
me.PurgeTimer = time.AfterFunc(me.ttl*5, c.PurgeTimer = time.AfterFunc(c.ttl*5,
func() { me.RecurringPurge() }) func() { c.RecurringPurge() })
} }
func (me *TimedCache) DropAll(names []string) { func (c *TimedCache) DropAll(names []string) {
me.cacheMapMutex.Lock() c.cacheMapMutex.Lock()
defer me.cacheMapMutex.Unlock() defer c.cacheMapMutex.Unlock()
if names == nil { if names == nil {
me.cacheMap = make(map[string]*cacheEntry, len(me.cacheMap)) c.cacheMap = make(map[string]*cacheEntry, len(c.cacheMap))
} else { } else {
for _, nm := range names { for _, nm := range names {
delete(me.cacheMap, nm) delete(c.cacheMap, nm)
} }
} }
} }
This diff is collapsed.
...@@ -30,24 +30,24 @@ func NewMemTreeFs() *MemTreeFs { ...@@ -30,24 +30,24 @@ func NewMemTreeFs() *MemTreeFs {
return d return d
} }
func (me *MemTreeFs) OnMount(conn *fuse.FileSystemConnector) { func (fs *MemTreeFs) OnMount(conn *fuse.FileSystemConnector) {
for k, v := range me.files { for k, v := range fs.files {
me.addFile(k, v) fs.addFile(k, v)
} }
me.files = nil fs.files = nil
} }
func (me *MemTreeFs) Root() fuse.FsNode { func (fs *MemTreeFs) Root() fuse.FsNode {
return &me.root return &fs.root
} }
func (me *memNode) Print(indent int) { func (n *memNode) Print(indent int) {
s := "" s := ""
for i := 0; i < indent; i++ { for i := 0; i < indent; i++ {
s = s + " " s = s + " "
} }
children := me.Inode().Children() children := n.Inode().Children()
for k, v := range children { for k, v := range children {
if v.IsDir() { if v.IsDir() {
fmt.Println(s + k + ":") fmt.Println(s + k + ":")
...@@ -62,12 +62,12 @@ func (me *memNode) Print(indent int) { ...@@ -62,12 +62,12 @@ func (me *memNode) Print(indent int) {
} }
// We construct the tree at mount, so we never need to look anything up. // 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 return nil, nil, fuse.ENOENT
} }
func (me *memNode) OpenDir(context *fuse.Context) (stream chan fuse.DirEntry, code fuse.Status) { func (n *memNode) OpenDir(context *fuse.Context) (stream chan fuse.DirEntry, code fuse.Status) {
children := me.Inode().Children() children := n.Inode().Children()
stream = make(chan fuse.DirEntry, len(children)) stream = make(chan fuse.DirEntry, len(children))
for k, v := range children { for k, v := range children {
mode := fuse.S_IFREG | 0666 mode := fuse.S_IFREG | 0666
...@@ -83,32 +83,32 @@ func (me *memNode) OpenDir(context *fuse.Context) (stream chan fuse.DirEntry, co ...@@ -83,32 +83,32 @@ func (me *memNode) OpenDir(context *fuse.Context) (stream chan fuse.DirEntry, co
return stream, fuse.OK 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 { if flags&fuse.O_ANYWRITE != 0 {
return nil, fuse.EPERM 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 return false
} }
func (me *memNode) GetAttr(file fuse.File, context *fuse.Context) (*fuse.Attr, fuse.Status) { func (n *memNode) GetAttr(file fuse.File, context *fuse.Context) (*fuse.Attr, fuse.Status) {
if me.Inode().IsDir() { if n.Inode().IsDir() {
return &fuse.Attr{ return &fuse.Attr{
Mode: fuse.S_IFDIR | 0777, Mode: fuse.S_IFDIR | 0777,
}, fuse.OK }, 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, "/") comps := strings.Split(name, "/")
node := me.root.Inode() node := n.root.Inode()
for i, c := range comps { for i, c := range comps {
child := node.GetChild(c) child := node.GetChild(c)
if child == nil { if child == nil {
......
...@@ -42,19 +42,19 @@ func NewMultiZipFs() *MultiZipFs { ...@@ -42,19 +42,19 @@ func NewMultiZipFs() *MultiZipFs {
return m return m
} }
func (me *MultiZipFs) String() string { func (fs *MultiZipFs) String() string {
return "MultiZipFs" return "MultiZipFs"
} }
func (me *MultiZipFs) OnMount(nodeFs *fuse.PathNodeFs) { func (fs *MultiZipFs) OnMount(nodeFs *fuse.PathNodeFs) {
me.nodeFs = nodeFs fs.nodeFs = nodeFs
} }
func (me *MultiZipFs) OpenDir(name string, context *fuse.Context) (stream chan fuse.DirEntry, code fuse.Status) { func (fs *MultiZipFs) OpenDir(name string, context *fuse.Context) (stream chan fuse.DirEntry, code fuse.Status) {
me.lock.RLock() fs.lock.RLock()
defer me.lock.RUnlock() defer fs.lock.RUnlock()
stream = make(chan fuse.DirEntry, len(me.zips)+2) stream = make(chan fuse.DirEntry, len(fs.zips)+2)
if name == "" { if name == "" {
var d fuse.DirEntry var d fuse.DirEntry
d.Name = "config" d.Name = "config"
...@@ -63,7 +63,7 @@ func (me *MultiZipFs) OpenDir(name string, context *fuse.Context) (stream chan f ...@@ -63,7 +63,7 @@ func (me *MultiZipFs) OpenDir(name string, context *fuse.Context) (stream chan f
} }
if name == "config" { if name == "config" {
for k := range me.zips { for k := range fs.zips {
var d fuse.DirEntry var d fuse.DirEntry
d.Name = k d.Name = k
d.Mode = fuse.S_IFLNK d.Mode = fuse.S_IFLNK
...@@ -75,7 +75,7 @@ func (me *MultiZipFs) OpenDir(name string, context *fuse.Context) (stream chan f ...@@ -75,7 +75,7 @@ func (me *MultiZipFs) OpenDir(name string, context *fuse.Context) (stream chan f
return stream, fuse.OK 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{} a := &fuse.Attr{}
if name == "" { if name == "" {
// Should not write in top dir. // Should not write in top dir.
...@@ -97,11 +97,11 @@ func (me *MultiZipFs) GetAttr(name string, context *fuse.Context) (*fuse.Attr, f ...@@ -97,11 +97,11 @@ func (me *MultiZipFs) GetAttr(name string, context *fuse.Context) (*fuse.Attr, f
submode = fuse.S_IFLNK | 0600 submode = fuse.S_IFLNK | 0600
} }
me.lock.RLock() fs.lock.RLock()
defer me.lock.RUnlock() defer fs.lock.RUnlock()
a.Mode = submode a.Mode = submode
_, hasDir := me.zips[base] _, hasDir := fs.zips[base]
if hasDir { if hasDir {
return a, fuse.OK return a, fuse.OK
} }
...@@ -109,20 +109,20 @@ func (me *MultiZipFs) GetAttr(name string, context *fuse.Context) (*fuse.Attr, f ...@@ -109,20 +109,20 @@ func (me *MultiZipFs) GetAttr(name string, context *fuse.Context) (*fuse.Attr, f
return nil, fuse.ENOENT 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) dir, basename := filepath.Split(name)
if dir == CONFIG_PREFIX { if dir == CONFIG_PREFIX {
me.lock.Lock() fs.lock.Lock()
defer me.lock.Unlock() defer fs.lock.Unlock()
zfs, ok := me.zips[basename] zfs, ok := fs.zips[basename]
if ok { if ok {
code = me.nodeFs.UnmountNode(zfs.Root().Inode()) code = fs.nodeFs.UnmountNode(zfs.Root().Inode())
if !code.Ok() { if !code.Ok() {
return code return code
} }
delete(me.zips, basename) delete(fs.zips, basename)
delete(me.dirZipFileMap, basename) delete(fs.dirZipFileMap, basename)
return fuse.OK return fuse.OK
} else { } else {
return fuse.ENOENT return fuse.ENOENT
...@@ -131,48 +131,48 @@ func (me *MultiZipFs) Unlink(name string, context *fuse.Context) (code fuse.Stat ...@@ -131,48 +131,48 @@ func (me *MultiZipFs) Unlink(name string, context *fuse.Context) (code fuse.Stat
return fuse.EPERM 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) dir, base := filepath.Split(path)
if dir != CONFIG_PREFIX { if dir != CONFIG_PREFIX {
return "", fuse.ENOENT return "", fuse.ENOENT
} }
me.lock.Lock() fs.lock.Lock()
defer me.lock.Unlock() defer fs.lock.Unlock()
zipfile, ok := me.dirZipFileMap[base] zipfile, ok := fs.dirZipFileMap[base]
if !ok { if !ok {
return "", fuse.ENOENT return "", fuse.ENOENT
} }
return zipfile, fuse.OK 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) dir, base := filepath.Split(linkName)
if dir != CONFIG_PREFIX { if dir != CONFIG_PREFIX {
return fuse.EPERM return fuse.EPERM
} }
me.lock.Lock() fs.lock.Lock()
defer me.lock.Unlock() defer fs.lock.Unlock()
_, ok := me.dirZipFileMap[base] _, ok := fs.dirZipFileMap[base]
if ok { if ok {
return fuse.EBUSY return fuse.EBUSY
} }
fs, err := NewArchiveFileSystem(value) afs, err := NewArchiveFileSystem(value)
if err != nil { if err != nil {
log.Println("NewZipArchiveFileSystem failed.", err) log.Println("NewZipArchiveFileSystem failed.", err)
return fuse.EINVAL return fuse.EINVAL
} }
code = me.nodeFs.Mount(base, fs, nil) code = fs.nodeFs.Mount(base, afs, nil)
if !code.Ok() { if !code.Ok() {
return code return code
} }
me.dirZipFileMap[base] = value fs.dirZipFileMap[base] = value
me.zips[base] = fs fs.zips[base] = afs
return fuse.OK return fuse.OK
} }
...@@ -33,14 +33,14 @@ type TarFile struct { ...@@ -33,14 +33,14 @@ type TarFile struct {
tar.Header tar.Header
} }
func (me *TarFile) Stat() *fuse.Attr { func (f *TarFile) Stat() *fuse.Attr {
fi, _ := HeaderToFileInfo(&me.Header) fi, _ := HeaderToFileInfo(&f.Header)
fi.Mode |= syscall.S_IFREG fi.Mode |= syscall.S_IFREG
return fi return fi
} }
func (me *TarFile) Data() []byte { func (f *TarFile) Data() []byte {
return me.data return f.data
} }
func NewTarTree(r io.Reader) map[string]MemFile { func NewTarTree(r io.Reader) map[string]MemFile {
......
...@@ -19,23 +19,23 @@ type ZipFile struct { ...@@ -19,23 +19,23 @@ type ZipFile struct {
*zip.File *zip.File
} }
func (me *ZipFile) Stat() *fuse.Attr { func (f *ZipFile) Stat() *fuse.Attr {
// TODO - do something intelligent with timestamps. // TODO - do something intelligent with timestamps.
return &fuse.Attr{ return &fuse.Attr{
Mode: fuse.S_IFREG | 0444, Mode: fuse.S_IFREG | 0444,
Size: uint64(me.File.UncompressedSize), Size: uint64(f.File.UncompressedSize),
} }
} }
func (me *ZipFile) Data() []byte { func (f *ZipFile) Data() []byte {
zf := (*me) zf := (*f)
rc, err := zf.Open() rc, err := zf.Open()
if err != nil { if err != nil {
panic(err) 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 { if err != nil {
panic(err) panic(err)
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment