Commit 5fd3a354 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Fix deadlock, and improve OpenDir() performance.

parent 7f8cd667
...@@ -24,6 +24,8 @@ type MemUnionFs struct { ...@@ -24,6 +24,8 @@ type MemUnionFs struct {
cond *sync.Cond cond *sync.Cond
nextFree int nextFree int
// TODO - should clear out backing every X file creations, to clean up unused files.
readonly fuse.FileSystem readonly fuse.FileSystem
openWritable int openWritable int
...@@ -379,6 +381,7 @@ func (me *memNode) Create(name string, flags uint32, mode uint32, context *fuse. ...@@ -379,6 +381,7 @@ func (me *memNode) Create(name string, flags uint32, mode uint32, context *fuse.
n.backing = me.fs.getFilename() n.backing = me.fs.getFilename()
f, err := os.Create(n.backing) f, err := os.Create(n.backing)
if err != nil { if err != nil {
log.Printf("Backing store error %q: %v", n.backing, err)
return nil, nil, nil, fuse.OsErrorToErrno(err) return nil, nil, nil, fuse.OsErrorToErrno(err)
} }
me.Inode().AddChild(name, n.Inode()) me.Inode().AddChild(name, n.Inode())
...@@ -475,12 +478,16 @@ func (me *memNode) Open(flags uint32, context *fuse.Context) (file fuse.File, co ...@@ -475,12 +478,16 @@ func (me *memNode) Open(flags uint32, context *fuse.Context) (file fuse.File, co
} }
func (me *memNode) GetAttr(file fuse.File, context *fuse.Context) (fi *os.FileInfo, code fuse.Status) { func (me *memNode) GetAttr(file fuse.File, context *fuse.Context) (fi *os.FileInfo, code fuse.Status) {
var sz int64
if file != nil {
fi, _ := file.GetAttr()
sz = fi.Size
}
me.mutex.RLock() me.mutex.RLock()
defer me.mutex.RUnlock() defer me.mutex.RUnlock()
info := me.info info := me.info
if file != nil { if file != nil {
fi, _ := file.GetAttr() info.Size = sz
info.Size = fi.Size
} }
return &info, fuse.OK return &info, fuse.OK
} }
...@@ -547,11 +554,7 @@ func (me *memNode) OpenDir(context *fuse.Context) (stream chan fuse.DirEntry, co ...@@ -547,11 +554,7 @@ func (me *memNode) OpenDir(context *fuse.Context) (stream chan fuse.DirEntry, co
} }
for k, n := range me.Inode().FsChildren() { for k, n := range me.Inode().FsChildren() {
fi, code := n.FsNode().GetAttr(nil, nil) ch[k] = n.FsNode().(*memNode).info.Mode
if !code.Ok() {
panic("child does not have mode.")
}
ch[k] = fi.Mode
} }
stream = make(chan fuse.DirEntry, len(ch)) stream = make(chan fuse.DirEntry, len(ch))
......
...@@ -222,7 +222,7 @@ func TestMemUnionFsPromote(t *testing.T) { ...@@ -222,7 +222,7 @@ func TestMemUnionFsPromote(t *testing.T) {
} }
} }
func TestMemUnionFsCreate(t *testing.T) { func TestMemUnionFsSubdirCreate(t *testing.T) {
wd, ufs, clean := setupMemUfs(t) wd, ufs, clean := setupMemUfs(t)
defer clean() defer clean()
...@@ -238,6 +238,20 @@ func TestMemUnionFsCreate(t *testing.T) { ...@@ -238,6 +238,20 @@ func TestMemUnionFsCreate(t *testing.T) {
} }
} }
func TestMemUnionFsCreate(t *testing.T) {
wd, ufs, clean := setupMemUfs(t)
defer clean()
writeToFile(wd+"/mount/file.txt", "hello")
_, err := os.Lstat(wd + "/mount/file.txt")
CheckSuccess(err)
r := ufs.Reap()
if r["file.txt"] == nil || r["file.txt"].Backing == "" {
t.Errorf("expect 1 file reap result: %v", r)
}
}
func TestMemUnionFsOpenUndeletes(t *testing.T) { func TestMemUnionFsOpenUndeletes(t *testing.T) {
wd, _, clean := setupMemUfs(t) wd, _, clean := setupMemUfs(t)
defer clean() defer clean()
......
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