Commit 38077f24 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

UnionFs: Create should mkdir up to the file in the writable branch.

parent 9f60272a
......@@ -262,7 +262,7 @@ func (me *UnionFs) Rmdir(path string) (code fuse.Status) {
if r.code != fuse.OK {
return r.code
}
if r.attr.Mode & fuse.S_IFDIR == 0 {
if r.attr.Mode&fuse.S_IFDIR == 0 {
return syscall.ENOTDIR
}
if r.branch > 0 {
......@@ -321,7 +321,7 @@ func (me *UnionFs) Chmod(name string, mode uint32) (code fuse.Status) {
return r.code
}
if r.attr.Mode & fuse.S_IFREG == 0 {
if r.attr.Mode&fuse.S_IFREG == 0 {
return fuse.EPERM
}
......@@ -375,10 +375,30 @@ func (me *UnionFs) Readlink(name string) (out string, code fuse.Status) {
return "", fuse.ENOENT
}
func IsDir(fs fuse.FileSystem, name string) bool {
a, code := fs.GetAttr(name)
return code == fuse.OK && a.Mode & fuse.S_IFDIR != 0
}
func (me *UnionFs) makeDirTo(name string) fuse.Status {
dir, base := filepath.Split(name)
if base != "" && !IsDir(me.fileSystems[0], dir) {
err := os.MkdirAll(me.branches[0].GetPath(dir), 0755)
if err != nil {
log.Println("Error creating dir leading to path", name, err)
return fuse.EPERM
}
}
return fuse.OK
}
func (me *UnionFs) Create(name string, flags uint32, mode uint32) (fuseFile fuse.File, code fuse.Status) {
// TODO(hanwen) - we should check that the name is not a
// directory in another branch.
writable := me.fileSystems[0]
code = me.makeDirTo(name)
if code != fuse.OK {
return nil, code
}
fuseFile, code = writable.Create(name, flags, mode)
if code == fuse.OK {
me.removeDeletion(name)
......
......@@ -17,7 +17,6 @@ func TestFilePathHash(t *testing.T) {
t.Log(filePathHash("xyz/abc"))
}
var testOpts = UnionFsOptions{
DeletionCacheTTLSecs: 0.01,
DeletionDirName: "DELETIONS",
......@@ -237,6 +236,19 @@ func TestPromote(t *testing.T) {
writeToFile(wd + "/mount/subdir/file", "other-content", false)
}
func TestCreate(t *testing.T) {
wd, state := setup(t)
defer state.Unmount()
err := os.MkdirAll(wd + "/ro/subdir/sub2", 0755)
CheckSuccess(err)
writeToFile(wd + "/mount/subdir/sub2/file", "other-content", true)
_, err = os.Lstat(wd + "/mount/subdir/sub2/file")
CheckSuccess(err)
}
func TestMkdir(t *testing.T) {
wd, state := setup(t)
defer 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