Commit 4d9a8aee authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Let UnionFs expose 3 cache drop functions publically.

Test for behavior of deletion cache drop too.
parent 98b666ce
...@@ -720,10 +720,17 @@ func (me *UnionFs) Rename(src string, dst string) (code fuse.Status) { ...@@ -720,10 +720,17 @@ func (me *UnionFs) Rename(src string, dst string) (code fuse.Status) {
return code return code
} }
func (me *UnionFs) DropCaches() { // TODO - a DropBranchCache which takes a list of names.
log.Println("Forced cache drop on", me.name)
func (me *UnionFs) DropBranchCache() {
me.branchCache.DropAll() me.branchCache.DropAll()
}
func (me *UnionFs) DropDeletionCache() {
me.deletionCache.DropCache() me.deletionCache.DropCache()
}
func (me *UnionFs) DropSubFsCaches() {
for _, fs := range me.fileSystems { for _, fs := range me.fileSystems {
a, code := fs.GetAttr(_DROP_CACHE) a, code := fs.GetAttr(_DROP_CACHE)
if code.Ok() && a.IsRegular() { if code.Ok() && a.IsRegular() {
...@@ -739,7 +746,10 @@ func (me *UnionFs) DropCaches() { ...@@ -739,7 +746,10 @@ func (me *UnionFs) DropCaches() {
func (me *UnionFs) Open(name string, flags uint32) (fuseFile fuse.File, status fuse.Status) { func (me *UnionFs) Open(name string, flags uint32) (fuseFile fuse.File, status fuse.Status) {
if name == _DROP_CACHE { if name == _DROP_CACHE {
if flags&fuse.O_ANYWRITE != 0 { if flags&fuse.O_ANYWRITE != 0 {
me.DropCaches() log.Println("Forced cache drop on", me.name)
me.DropBranchCache()
me.DropDeletionCache()
me.DropSubFsCaches()
} }
return fuse.NewDevNullFile(), fuse.OK return fuse.NewDevNullFile(), fuse.OK
} }
......
...@@ -44,10 +44,12 @@ func setupUfs(t *testing.T) (workdir string, cleanup func()) { ...@@ -44,10 +44,12 @@ func setupUfs(t *testing.T) (workdir string, cleanup func()) {
NewCachingFileSystem(fuse.NewLoopbackFileSystem(wd+"/ro"), 0)) NewCachingFileSystem(fuse.NewLoopbackFileSystem(wd+"/ro"), 0))
ufs := NewUnionFs("testFs", fses, testOpts) ufs := NewUnionFs("testFs", fses, testOpts)
// We configure timeouts are smaller, so we can check for
// UnionFs's cache consistency.
opts := &fuse.FileSystemOptions{ opts := &fuse.FileSystemOptions{
EntryTimeout: entryTtl, EntryTimeout: .5 * entryTtl,
AttrTimeout: entryTtl, AttrTimeout: .5 * entryTtl,
NegativeTimeout: entryTtl, NegativeTimeout: .5 * entryTtl,
} }
state, _, err := fuse.MountFileSystem(wd+"/mount", ufs, opts) state, _, err := fuse.MountFileSystem(wd+"/mount", ufs, opts)
...@@ -541,6 +543,43 @@ func Readdirnames(dir string) ([]string, os.Error) { ...@@ -541,6 +543,43 @@ func Readdirnames(dir string) ([]string, os.Error) {
return f.Readdirnames(-1) return f.Readdirnames(-1)
} }
func TestDropDeletionCache(t *testing.T) {
t.Log("TestDropDeletionCache")
wd, clean := setupUfs(t)
defer clean()
err := ioutil.WriteFile(wd+"/ro/file", []byte("bla"), 0644)
CheckSuccess(err)
_, err = os.Lstat(wd + "/mount/file")
CheckSuccess(err)
err = os.Remove(wd + "/mount/file")
CheckSuccess(err)
fi, _ := os.Lstat(wd + "/mount/file")
if fi != nil {
t.Fatal("Lstat() should have failed", fi)
}
names, err := Readdirnames(wd + "/rw/DELETIONS")
CheckSuccess(err)
if len(names) != 1 {
t.Fatal("unexpected names", names)
}
os.Remove(wd + "/rw/DELETIONS/" + names[0])
fi, _ = os.Lstat(wd + "/mount/file")
if fi != nil {
t.Fatal("Lstat() should have failed", fi)
}
// Expire kernel entry.
time.Sleep(0.6e9 * entryTtl)
err = ioutil.WriteFile(wd+"/mount/.drop_cache", []byte(""), 0644)
CheckSuccess(err)
_, err = os.Lstat(wd + "/mount/file")
if err != nil {
t.Fatal("Lstat() should have succeeded", err)
}
}
func TestDropCache(t *testing.T) { func TestDropCache(t *testing.T) {
t.Log("TestDropCache") t.Log("TestDropCache")
wd, clean := setupUfs(t) wd, clean := setupUfs(t)
......
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