Commit ef5d1063 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Add file/directory/mount tracking for proper EBUSY errors on mounts.

Extends raw API with Release() and ReleaseDir() methods.
parent 0f4e53e7
......@@ -97,6 +97,13 @@ func (self *DummyFuse) OpenDir(header *fuse.InHeader, input *fuse.OpenIn) (flags
return 0, nil, fuse.ENOSYS
}
func (self *DummyFuse) Release(header *fuse.InHeader, f fuse.RawFuseFile) {
}
func (self *DummyFuse) ReleaseDir(header *fuse.InHeader, f fuse.RawFuseDir) {
}
////////////////////////////////////////////////////////////////
// DummyFuseFile
......
......@@ -11,6 +11,7 @@ import (
"testing"
"syscall"
"rand"
"time"
)
var _ = strings.Join
......@@ -634,5 +635,25 @@ func TestRecursiveMount(t *testing.T) {
if err != nil {
t.Error("lstat submount/file", err)
}
f, err = os.Open(path.Join(submnt, "hello.txt"), os.O_RDONLY, 0)
if err != nil {
t.Error("open submount/file", err)
}
code = ts.connector.Unmount("/mnt")
if code != fuse.EBUSY {
t.Error("expect EBUSY")
}
f.Close()
// The close takes some time to propagate through FUSE.
time.Sleep(1e9)
code = ts.connector.Unmount("/mnt")
if code != fuse.OK {
t.Error("umount failed.", code)
}
ts.Cleanup()
}
......@@ -592,6 +592,16 @@ func (self *SubmountFileSystem) OpenDir(header *fuse.InHeader, input *fuse.OpenI
return subfs.Fs.OpenDir(header, input)
}
func (self *SubmountFileSystem) Release(header *fuse.InHeader, f fuse.RawFuseFile) {
// TODO - should run release on subfs too.
}
func (self *SubmountFileSystem) ReleaseDir(header *fuse.InHeader, f fuse.RawFuseDir) {
// TODO - should run releasedir on subfs too.
}
////////////////////////////////////////////////////////////////
type SubmountFileSystemTopDir struct {
......@@ -628,3 +638,4 @@ func (self *SubmountFileSystemTopDir) ReleaseDir() {
func (self *SubmountFileSystemTopDir) FsyncDir(input *fuse.FsyncIn) (code fuse.Status) {
return fuse.ENOENT
}
......@@ -501,7 +501,9 @@ func doCreate(state *MountState, header *InHeader, input *CreateIn, name string)
}
func doRelease(state *MountState, header *InHeader, input *ReleaseIn) (out Empty, code Status) {
state.FindFile(input.Fh).Release()
f := state.FindFile(input.Fh)
state.fileSystem.Release(header, f)
f.Release()
state.UnregisterFile(input.Fh)
return nil, OK
}
......@@ -534,7 +536,9 @@ func doSetattr(state *MountState, header *InHeader, input *SetAttrIn) (out *Attr
// Handling directories
func doReleaseDir(state *MountState, header *InHeader, input *ReleaseIn) (out Empty, code Status) {
state.FindDir(input.Fh).ReleaseDir()
d := state.FindDir(input.Fh)
state.fileSystem.ReleaseDir(header, d)
d.ReleaseDir()
state.UnregisterDir(input.Fh)
return nil, OK
}
......
This diff is collapsed.
......@@ -531,6 +531,9 @@ type RawFileSystem interface {
// The return flags are FOPEN_xx.
Open(header *InHeader, input *OpenIn) (flags uint32, fuseFile RawFuseFile, status Status)
OpenDir(header *InHeader, input *OpenIn) (flags uint32, fuseFile RawFuseDir, status Status)
Release(header *InHeader, f RawFuseFile)
ReleaseDir(header *InHeader, f RawFuseDir)
}
type RawFuseFile interface {
......
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