Commit 1f1c157d authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Allow different PathFilesystems to be mounted within directories of

PathFileSystemConnector file system.
parent 9d51ae3f
*~ *~
*.6 *.6
8.out
.nfs* .nfs*
_* _*
...@@ -21,9 +21,9 @@ func main() { ...@@ -21,9 +21,9 @@ func main() {
} }
orig := flag.Arg(0) orig := flag.Arg(0)
pt := examplelib.NewPassThroughFuse(orig) fs := examplelib.NewPassThroughFuse(orig)
fs := fuse.NewPathFileSystemConnector(pt) conn := fuse.NewPathFileSystemConnector(fs)
state := fuse.NewMountState(fs) state := fuse.NewMountState(conn)
state.Debug = *debug state.Debug = *debug
mountPoint := flag.Arg(1) mountPoint := flag.Arg(1)
......
...@@ -7,7 +7,8 @@ DEPS=../fuse ...@@ -7,7 +7,8 @@ DEPS=../fuse
GOFILES=dummyfuse.go\ GOFILES=dummyfuse.go\
passthrough.go\ passthrough.go\
stackfs.go stackfs.go\
misc.go
include $(GOROOT)/src/Make.pkg include $(GOROOT)/src/Make.pkg
...@@ -194,11 +194,11 @@ func (self *DummyPathFuse) OpenDir(name string) (dir fuse.RawFuseDir, code fuse. ...@@ -194,11 +194,11 @@ func (self *DummyPathFuse) OpenDir(name string) (dir fuse.RawFuseDir, code fuse.
return nil, fuse.ENOSYS return nil, fuse.ENOSYS
} }
func (self *DummyPathFuse) Init() (*fuse.InitOut, fuse.Status) { func (self *DummyPathFuse) Mount(conn *fuse.PathFileSystemConnector) (fuse.Status) {
return nil, fuse.ENOSYS return fuse.OK
} }
func (self *DummyPathFuse) Destroy() { func (self *DummyPathFuse) Unmount() {
} }
func (self *DummyPathFuse) Access(name string, mode uint32) (code fuse.Status) { func (self *DummyPathFuse) Access(name string, mode uint32) (code fuse.Status) {
...@@ -213,6 +213,3 @@ func (self *DummyPathFuse) Utimens(name string, AtimeNs uint64, CtimeNs uint64) ...@@ -213,6 +213,3 @@ func (self *DummyPathFuse) Utimens(name string, AtimeNs uint64, CtimeNs uint64)
return fuse.ENOSYS return fuse.ENOSYS
} }
func (self *DummyPathFuse) SetOptions(*fuse.PathFileSystemConnectorOptions) {
}
package examplelib
import "os"
////////////////
func IsDir(name string) bool {
fi, _ := os.Lstat(name)
return fi != nil && fi.IsDirectory()
}
func IsFile(name string) bool {
fi, _ := os.Lstat(name)
return fi != nil && fi.IsRegular()
}
func FileExists(name string) bool {
_, err := os.Lstat(name)
return err == nil
}
...@@ -25,11 +25,11 @@ func NewPassThroughFuse(root string) (out *PassThroughFuse) { ...@@ -25,11 +25,11 @@ func NewPassThroughFuse(root string) (out *PassThroughFuse) {
return out return out
} }
func (self *PassThroughFuse) Init() (*fuse.InitOut, fuse.Status) { func (self *PassThroughFuse) Mount(conn *fuse.PathFileSystemConnector) (fuse.Status) {
return new(fuse.InitOut), fuse.OK return fuse.OK
} }
func (self *PassThroughFuse) Destroy() { func (self *PassThroughFuse) Unmount() {
} }
......
...@@ -16,23 +16,6 @@ import ( ...@@ -16,23 +16,6 @@ import (
var _ = strings.Join var _ = strings.Join
var _ = log.Println var _ = log.Println
////////////////
func IsDir(name string) bool {
fi, _ := os.Lstat(name)
return fi != nil && fi.IsDirectory()
}
func IsFile(name string) bool {
fi, _ := os.Lstat(name)
return fi != nil && fi.IsRegular()
}
func FileExists(name string) bool {
_, err := os.Lstat(name)
return err == nil
}
//////////////// ////////////////
// state for our testcase, mostly constants // state for our testcase, mostly constants
...@@ -50,6 +33,7 @@ type testCase struct { ...@@ -50,6 +33,7 @@ type testCase struct {
origSubfile string origSubfile string
tester *testing.T tester *testing.T
state *fuse.MountState state *fuse.MountState
connector *fuse.PathFileSystemConnector
} }
// Create and mount filesystem. // Create and mount filesystem.
...@@ -68,10 +52,11 @@ func (self *testCase) Setup(t *testing.T) { ...@@ -68,10 +52,11 @@ func (self *testCase) Setup(t *testing.T) {
self.origFile = path.Join(self.origDir, name) self.origFile = path.Join(self.origDir, name)
self.origSubdir = path.Join(self.origDir, subdir) self.origSubdir = path.Join(self.origDir, subdir)
self.origSubfile = path.Join(self.origSubdir, "subfile") self.origSubfile = path.Join(self.origSubdir, "subfile")
fs := fuse.NewPathFileSystemConnector(NewPassThroughFuse(self.origDir)) pfs := NewPassThroughFuse(self.origDir)
self.connector = fuse.NewPathFileSystemConnector(pfs)
self.state = fuse.NewMountState(fs) self.connector.Debug = true
self.state = fuse.NewMountState(self.connector)
self.state.Mount(self.mountPoint) self.state.Mount(self.mountPoint)
//self.state.Debug = false //self.state.Debug = false
...@@ -610,3 +595,44 @@ func TestMount(t *testing.T) { ...@@ -610,3 +595,44 @@ func TestMount(t *testing.T) {
ts.testLargeDirRead() ts.testLargeDirRead()
ts.Cleanup() ts.Cleanup()
} }
func TestRecursiveMount(t *testing.T) {
ts := new(testCase)
ts.Setup(t)
f, err := os.Open(path.Join(ts.mountPoint, "hello.txt"),
os.O_WRONLY|os.O_CREATE, 0777)
if err != nil {
t.Errorf("open write err %v", err)
}
f.WriteString("bla")
f.Close()
pfs2 := NewPassThroughFuse(ts.origDir)
code := ts.connector.Mount("/hello.txt", pfs2)
if code != fuse.EINVAL {
t.Error("expect EINVAL", code)
}
submnt := path.Join(ts.mountPoint, "mnt")
err = os.Mkdir(submnt, 0777)
if err != nil {
t.Errorf("mkdir")
}
code = ts.connector.Mount("/mnt", pfs2)
if code != fuse.OK {
t.Errorf("mkdir")
}
_, err = os.Lstat(submnt)
if err != nil {
t.Error("lstat submount", err)
}
_, err = os.Lstat(path.Join(submnt, "hello.txt"))
if err != nil {
t.Error("lstat submount/file", err)
}
ts.Cleanup()
}
...@@ -43,7 +43,7 @@ func (self *stackFsTestCase) Setup(t *testing.T) { ...@@ -43,7 +43,7 @@ func (self *stackFsTestCase) Setup(t *testing.T) {
fs1 := fuse.NewPathFileSystemConnector(NewPassThroughFuse(self.origDir1)) fs1 := fuse.NewPathFileSystemConnector(NewPassThroughFuse(self.origDir1))
fs2 := fuse.NewPathFileSystemConnector(NewPassThroughFuse(self.origDir2)) fs2 := fuse.NewPathFileSystemConnector(NewPassThroughFuse(self.origDir2))
self.fs = NewSubmountFileSystem() self.fs = NewSubmountFileSystem()
attr := fuse.Attr{ attr := fuse.Attr{
......
...@@ -31,7 +31,7 @@ func (de *DirEntryList) Add(name []byte, inode uint64, mode uint32) bool { ...@@ -31,7 +31,7 @@ func (de *DirEntryList) Add(name []byte, inode uint64, mode uint32) bool {
dirent.Off = de.offset dirent.Off = de.offset
dirent.Ino = inode dirent.Ino = inode
dirent.NameLen = uint32(len(name)) dirent.NameLen = uint32(len(name))
dirent.Typ = (mode & 0170000) >> 12 dirent.Typ = ModeToType(mode)
err := binary.Write(&de.buf, binary.LittleEndian, dirent) err := binary.Write(&de.buf, binary.LittleEndian, dirent)
if err != nil { if err != nil {
......
...@@ -291,3 +291,7 @@ func NegativeEntry(time float64) *EntryOut { ...@@ -291,3 +291,7 @@ func NegativeEntry(time float64) *EntryOut {
SplitNs(time, &out.EntryValid, &out.EntryValidNsec) SplitNs(time, &out.EntryValid, &out.EntryValidNsec)
return out return out
} }
func ModeToType(mode uint32) uint32 {
return (mode & 0170000) >> 12
}
This diff is collapsed.
...@@ -92,6 +92,9 @@ const ( ...@@ -92,6 +92,9 @@ const (
ENOTDIR = Status(syscall.ENOTDIR) ENOTDIR = Status(syscall.ENOTDIR)
EACCES = Status(syscall.EACCES) EACCES = Status(syscall.EACCES)
EPERM = Status(syscall.EPERM) EPERM = Status(syscall.EPERM)
EBUSY = Status(syscall.EBUSY)
EINVAL = Status(syscall.EINVAL)
EXDEV = Status(syscall.EXDEV)
) )
type Opcode int type Opcode int
...@@ -568,14 +571,12 @@ type PathFilesystem interface { ...@@ -568,14 +571,12 @@ type PathFilesystem interface {
OpenDir(name string) (dir RawFuseDir, code Status) OpenDir(name string) (dir RawFuseDir, code Status)
// TODO - what is a good interface? // TODO - what is a good interface?
Init() (*InitOut, Status) Mount(connector *PathFileSystemConnector) Status
Destroy() Unmount()
Access(name string, mode uint32) (code Status) Access(name string, mode uint32) (code Status)
Create(name string, flags uint32, mode uint32) (file RawFuseFile, code Status) Create(name string, flags uint32, mode uint32) (file RawFuseFile, code Status)
Utimens(name string, AtimeNs uint64, CtimeNs uint64) (code Status) Utimens(name string, AtimeNs uint64, CtimeNs uint64) (code Status)
// unimplemented: poll, ioctl, bmap. // unimplemented: poll, ioctl, bmap.
SetOptions(*PathFileSystemConnectorOptions)
} }
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