Commit 0f459cbf authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

MemUnionFs: wait for closes to reap unionfs.

parent 5b5bf08b
...@@ -20,9 +20,12 @@ type MemUnionFs struct { ...@@ -20,9 +20,12 @@ type MemUnionFs struct {
root *memNode root *memNode
mutex sync.RWMutex mutex sync.RWMutex
cond *sync.Cond
nextFree int nextFree int
readonly fuse.FileSystem readonly fuse.FileSystem
openWritable int
} }
type memNode struct { type memNode struct {
...@@ -46,10 +49,20 @@ type Result struct { ...@@ -46,10 +49,20 @@ type Result struct {
Link string Link string
} }
func (me *MemUnionFs) Reap() map[string]*Result { func (me *MemUnionFs) release() {
me.mutex.RLock() me.mutex.Lock()
defer me.mutex.RUnlock() defer me.mutex.Unlock()
me.openWritable--
me.cond.Broadcast()
}
func (me *MemUnionFs) Reap() map[string]*Result {
me.mutex.Lock()
defer me.mutex.Unlock()
for me.openWritable > 0 {
me.cond.Wait()
}
m := map[string]*Result{} m := map[string]*Result{}
me.root.Reap("", m) me.root.Reap("", m)
return m return m
...@@ -96,6 +109,7 @@ func NewMemUnionFs(backingStore string, roFs fuse.FileSystem) *MemUnionFs { ...@@ -96,6 +109,7 @@ func NewMemUnionFs(backingStore string, roFs fuse.FileSystem) *MemUnionFs {
me.backingStore = backingStore me.backingStore = backingStore
me.readonly = roFs me.readonly = roFs
me.root = me.newNode(true) me.root = me.newNode(true)
me.cond = sync.NewCond(&me.mutex)
return me return me
} }
...@@ -236,6 +250,7 @@ func (me *memNode) Create(name string, flags uint32, mode uint32, context *fuse. ...@@ -236,6 +250,7 @@ func (me *memNode) Create(name string, flags uint32, mode uint32, context *fuse.
me.Inode().AddChild(name, n.Inode()) me.Inode().AddChild(name, n.Inode())
me.touch() me.touch()
me.deleted[name] = false, false me.deleted[name] = false, false
me.fs.openWritable++
return n.newFile(&fuse.LoopbackFile{File: f}, true), &n.info, n, fuse.OK return n.newFile(&fuse.LoopbackFile{File: f}, true), &n.info, n, fuse.OK
} }
...@@ -249,6 +264,11 @@ func (me *memNodeFile) InnerFile() fuse.File { ...@@ -249,6 +264,11 @@ func (me *memNodeFile) InnerFile() fuse.File {
return me.File return me.File
} }
func (me *memNodeFile) Release() {
me.node.fs.release()
me.File.Release()
}
func (me *memNodeFile) Flush() fuse.Status { func (me *memNodeFile) Flush() fuse.Status {
code := me.File.Flush() code := me.File.Flush()
if me.writable { if me.writable {
...@@ -294,22 +314,22 @@ func (me *memNode) promote() { ...@@ -294,22 +314,22 @@ func (me *memNode) promote() {
} }
func (me *memNode) Open(flags uint32, context *fuse.Context) (file fuse.File, code fuse.Status) { func (me *memNode) Open(flags uint32, context *fuse.Context) (file fuse.File, code fuse.Status) {
me.mutex.Lock()
defer me.mutex.Unlock()
if flags&fuse.O_ANYWRITE != 0 { if flags&fuse.O_ANYWRITE != 0 {
me.mutex.Lock()
me.promote() me.promote()
me.touch() me.touch()
me.mutex.Unlock()
} }
me.mutex.RLock()
defer me.mutex.RUnlock()
if me.backing != "" { if me.backing != "" {
f, err := os.OpenFile(me.backing, int(flags), 0666) f, err := os.OpenFile(me.backing, int(flags), 0666)
if err != nil { if err != nil {
return nil, fuse.OsErrorToErrno(err) return nil, fuse.OsErrorToErrno(err)
} }
wr := flags&fuse.O_ANYWRITE != 0 wr := flags&fuse.O_ANYWRITE != 0
if wr {
me.fs.openWritable++
}
return me.newFile(&fuse.LoopbackFile{File: f}, wr), fuse.OK return me.newFile(&fuse.LoopbackFile{File: f}, wr), fuse.OK
} }
......
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