Commit 2fc99324 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Implement content caching too, and disable due to memory overflow.

parent 83a89fc7
package unionfs
import (
"bytes"
"fmt"
"github.com/hanwen/go-fuse/fuse"
"os"
......@@ -31,6 +32,11 @@ type linkResponse struct {
fuse.Status
}
type openResponse struct {
fuse.File
fuse.Status
}
// Caches readdir and getattr()
type CachingFileSystem struct {
fuse.FileSystem
......@@ -39,6 +45,7 @@ type CachingFileSystem struct {
dirs *TimedCache
links *TimedCache
xattr *TimedCache
files *TimedCache
}
func readDir(fs fuse.FileSystem, name string) *dirResponse {
......@@ -67,6 +74,43 @@ func getAttr(fs fuse.FileSystem, name string) *attrResponse {
}
}
func openFile(fs fuse.FileSystem, name string) (result *openResponse) {
result = &openResponse{}
flags := uint32(os.O_RDONLY)
f, code := fs.Open(name, flags)
if !code.Ok() {
result.Status = code
return
}
defer f.Release()
defer f.Flush()
buf := bytes.NewBuffer(nil)
input := fuse.ReadIn{
Offset: 0,
Size: 128 * (1<<10),
Flags: flags,
}
bp := fuse.NewGcBufferPool()
for {
data, status := f.Read(&input, bp)
buf.Write(data)
if !status.Ok() {
result.Status = status
return
}
if len(data) < int(input.Size) {
break
}
input.Offset += uint64(len(data))
}
result.File = fuse.NewReadOnlyFile(buf.Bytes())
return
}
func getXAttr(fs fuse.FileSystem, nameAttr string) *xattrResponse {
ns := strings.Split(nameAttr, _XATTRSEP, 2)
a, code := fs.GetXAttr(ns[0], ns[1])
......@@ -93,6 +137,9 @@ func NewCachingFileSystem(fs fuse.FileSystem, ttlNs int64) *CachingFileSystem {
c.xattr = NewTimedCache(func(n string) interface{} {
return getXAttr(fs, n)
},ttlNs)
c.files = NewTimedCache(func(n string) interface{} {
return openFile(fs, n)
},ttlNs)
return c
}
......@@ -131,3 +178,13 @@ func (me *CachingFileSystem) OpenDir(name string) (stream chan fuse.DirEntry, st
return nil, r.Status
}
// Caching file contents easily overflows available memory.
func (me *CachingFileSystem) DisabledOpen(name string, flags uint32) (f fuse.File, status fuse.Status) {
if flags & fuse.O_ANYWRITE != 0 {
return nil, fuse.EPERM
}
r := me.files.Get(name).(*openResponse)
return r.File, r.Status
}
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