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 ...@@ -97,6 +97,13 @@ func (self *DummyFuse) OpenDir(header *fuse.InHeader, input *fuse.OpenIn) (flags
return 0, nil, fuse.ENOSYS 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 // DummyFuseFile
......
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"testing" "testing"
"syscall" "syscall"
"rand" "rand"
"time"
) )
var _ = strings.Join var _ = strings.Join
...@@ -634,5 +635,25 @@ func TestRecursiveMount(t *testing.T) { ...@@ -634,5 +635,25 @@ func TestRecursiveMount(t *testing.T) {
if err != nil { if err != nil {
t.Error("lstat submount/file", err) 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() ts.Cleanup()
} }
...@@ -592,6 +592,16 @@ func (self *SubmountFileSystem) OpenDir(header *fuse.InHeader, input *fuse.OpenI ...@@ -592,6 +592,16 @@ func (self *SubmountFileSystem) OpenDir(header *fuse.InHeader, input *fuse.OpenI
return subfs.Fs.OpenDir(header, input) 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 { type SubmountFileSystemTopDir struct {
...@@ -628,3 +638,4 @@ func (self *SubmountFileSystemTopDir) ReleaseDir() { ...@@ -628,3 +638,4 @@ func (self *SubmountFileSystemTopDir) ReleaseDir() {
func (self *SubmountFileSystemTopDir) FsyncDir(input *fuse.FsyncIn) (code fuse.Status) { func (self *SubmountFileSystemTopDir) FsyncDir(input *fuse.FsyncIn) (code fuse.Status) {
return fuse.ENOENT return fuse.ENOENT
} }
...@@ -501,7 +501,9 @@ func doCreate(state *MountState, header *InHeader, input *CreateIn, name string) ...@@ -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) { 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) state.UnregisterFile(input.Fh)
return nil, OK return nil, OK
} }
...@@ -534,7 +536,9 @@ func doSetattr(state *MountState, header *InHeader, input *SetAttrIn) (out *Attr ...@@ -534,7 +536,9 @@ func doSetattr(state *MountState, header *InHeader, input *SetAttrIn) (out *Attr
// Handling directories // Handling directories
func doReleaseDir(state *MountState, header *InHeader, input *ReleaseIn) (out Empty, code Status) { 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) state.UnregisterDir(input.Fh)
return nil, OK return nil, OK
} }
......
This diff is collapsed.
...@@ -531,6 +531,9 @@ type RawFileSystem interface { ...@@ -531,6 +531,9 @@ type RawFileSystem interface {
// The return flags are FOPEN_xx. // The return flags are FOPEN_xx.
Open(header *InHeader, input *OpenIn) (flags uint32, fuseFile RawFuseFile, status Status) Open(header *InHeader, input *OpenIn) (flags uint32, fuseFile RawFuseFile, status Status)
OpenDir(header *InHeader, input *OpenIn) (flags uint32, fuseFile RawFuseDir, 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 { 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