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
8.out
.nfs*
_*
......@@ -21,9 +21,9 @@ func main() {
}
orig := flag.Arg(0)
pt := examplelib.NewPassThroughFuse(orig)
fs := fuse.NewPathFileSystemConnector(pt)
state := fuse.NewMountState(fs)
fs := examplelib.NewPassThroughFuse(orig)
conn := fuse.NewPathFileSystemConnector(fs)
state := fuse.NewMountState(conn)
state.Debug = *debug
mountPoint := flag.Arg(1)
......
......@@ -7,7 +7,8 @@ DEPS=../fuse
GOFILES=dummyfuse.go\
passthrough.go\
stackfs.go
stackfs.go\
misc.go
include $(GOROOT)/src/Make.pkg
......@@ -194,11 +194,11 @@ func (self *DummyPathFuse) OpenDir(name string) (dir fuse.RawFuseDir, code fuse.
return nil, fuse.ENOSYS
}
func (self *DummyPathFuse) Init() (*fuse.InitOut, fuse.Status) {
return nil, fuse.ENOSYS
func (self *DummyPathFuse) Mount(conn *fuse.PathFileSystemConnector) (fuse.Status) {
return fuse.OK
}
func (self *DummyPathFuse) Destroy() {
func (self *DummyPathFuse) Unmount() {
}
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)
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) {
return out
}
func (self *PassThroughFuse) Init() (*fuse.InitOut, fuse.Status) {
return new(fuse.InitOut), fuse.OK
func (self *PassThroughFuse) Mount(conn *fuse.PathFileSystemConnector) (fuse.Status) {
return fuse.OK
}
func (self *PassThroughFuse) Destroy() {
func (self *PassThroughFuse) Unmount() {
}
......
......@@ -16,23 +16,6 @@ import (
var _ = strings.Join
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
......@@ -50,6 +33,7 @@ type testCase struct {
origSubfile string
tester *testing.T
state *fuse.MountState
connector *fuse.PathFileSystemConnector
}
// Create and mount filesystem.
......@@ -68,10 +52,11 @@ func (self *testCase) Setup(t *testing.T) {
self.origFile = path.Join(self.origDir, name)
self.origSubdir = path.Join(self.origDir, subdir)
self.origSubfile = path.Join(self.origSubdir, "subfile")
fs := fuse.NewPathFileSystemConnector(NewPassThroughFuse(self.origDir))
self.state = fuse.NewMountState(fs)
pfs := NewPassThroughFuse(self.origDir)
self.connector = fuse.NewPathFileSystemConnector(pfs)
self.connector.Debug = true
self.state = fuse.NewMountState(self.connector)
self.state.Mount(self.mountPoint)
//self.state.Debug = false
......@@ -610,3 +595,44 @@ func TestMount(t *testing.T) {
ts.testLargeDirRead()
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) {
fs1 := fuse.NewPathFileSystemConnector(NewPassThroughFuse(self.origDir1))
fs2 := fuse.NewPathFileSystemConnector(NewPassThroughFuse(self.origDir2))
self.fs = NewSubmountFileSystem()
attr := fuse.Attr{
......
......@@ -31,7 +31,7 @@ func (de *DirEntryList) Add(name []byte, inode uint64, mode uint32) bool {
dirent.Off = de.offset
dirent.Ino = inode
dirent.NameLen = uint32(len(name))
dirent.Typ = (mode & 0170000) >> 12
dirent.Typ = ModeToType(mode)
err := binary.Write(&de.buf, binary.LittleEndian, dirent)
if err != nil {
......
......@@ -291,3 +291,7 @@ func NegativeEntry(time float64) *EntryOut {
SplitNs(time, &out.EntryValid, &out.EntryValidNsec)
return out
}
func ModeToType(mode uint32) uint32 {
return (mode & 0170000) >> 12
}
This diff is collapsed.
......@@ -92,6 +92,9 @@ const (
ENOTDIR = Status(syscall.ENOTDIR)
EACCES = Status(syscall.EACCES)
EPERM = Status(syscall.EPERM)
EBUSY = Status(syscall.EBUSY)
EINVAL = Status(syscall.EINVAL)
EXDEV = Status(syscall.EXDEV)
)
type Opcode int
......@@ -568,14 +571,12 @@ type PathFilesystem interface {
OpenDir(name string) (dir RawFuseDir, code Status)
// TODO - what is a good interface?
Init() (*InitOut, Status)
Destroy()
Mount(connector *PathFileSystemConnector) Status
Unmount()
Access(name string, mode uint32) (code Status)
Create(name string, flags uint32, mode uint32) (file RawFuseFile, code Status)
Utimens(name string, AtimeNs uint64, CtimeNs uint64) (code Status)
// 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