Commit 8b62c828 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Implement Rename in UnionFs.

parent c9da078c
......@@ -468,6 +468,39 @@ func (me *UnionFs) OpenDir(directory string) (stream chan fuse.DirEntry, status
return stream, fuse.OK
}
func (me *UnionFs) Rename(src string, dst string) (status fuse.Status) {
srcResult := me.branchCache.Get(src).(getBranchResult)
if srcResult.code != fuse.OK {
return srcResult.code
}
if srcResult.branch > 0 {
code := me.Promote(src, me.branches[srcResult.branch])
if code != fuse.OK {
return code
}
}
code := me.fileSystems[0].Rename(src, dst)
if code != fuse.OK {
return code
}
me.removeDeletion(dst)
srcResult.branch = 0
me.branchCache.Set(dst, srcResult)
if srcResult.branch == 0 {
srcResult := me.branchCache.getDataNoCache(src)
if srcResult.(getBranchResult).branch > 0 {
code = me.putDeletion(src)
}
} else {
code = me.putDeletion(src)
}
return code
}
func (me *UnionFs) Open(name string, flags uint32) (fuseFile fuse.File, status fuse.Status) {
branch := me.getBranch(name)
if flags&fuse.O_ANYWRITE != 0 && branch > 0 {
......
......@@ -43,7 +43,7 @@ func setup(t *testing.T) (workdir string, state *fuse.MountState) {
connector := fuse.NewFileSystemConnector(ufs, nil)
state = fuse.NewMountState(connector)
state.Mount(wd + "/mount")
// state.Debug = true
go state.Loop(false)
return wd, state
......@@ -236,3 +236,62 @@ func TestPromote(t *testing.T) {
writeToFile(wd + "/ro/subdir/file", "content", true)
writeToFile(wd + "/mount/subdir/file", "other-content", false)
}
func TestRename(t *testing.T) {
type Config struct {
f1_ro bool
f1_rw bool
f2_ro bool
f2_rw bool
}
configs := make([]Config, 0)
for i := 0; i < 16; i++ {
c := Config{i&0x1 != 0, i&0x2 != 0, i&0x4 != 0, i&0x8 != 0}
if !(c.f1_ro || c.f1_rw) {
continue
}
configs = append(configs, c)
}
for i, c := range configs {
t.Log("Config", i, c)
wd, state := setup(t)
if c.f1_ro {
writeToFile(wd + "/ro/file1", "c1", true)
}
if c.f1_rw {
writeToFile(wd + "/rw/file1", "c2", true)
}
if c.f2_ro {
writeToFile(wd + "/ro/file2", "c3", true)
}
if c.f2_rw {
writeToFile(wd + "/rw/file2", "c4", true)
}
err := os.Rename(wd + "/mount/file1", wd + "/mount/file2")
CheckSuccess(err)
_, err = os.Lstat(wd + "/mount/file1")
if err == nil {
t.Errorf("Should have lost file1")
}
_, err = os.Lstat(wd + "/mount/file2")
CheckSuccess(err)
err = os.Rename(wd + "/mount/file2", wd + "/mount/file1")
CheckSuccess(err)
_, err = os.Lstat(wd + "/mount/file2")
if err == nil {
t.Errorf("Should have lost file2")
}
_, err = os.Lstat(wd + "/mount/file1")
CheckSuccess(err)
state.Unmount()
}
}
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