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

Merge remote branch 'origin/master' into gcopt

parents 0b0f4ddb 9e57c957
*~
*.6
8.out
.nfs*
_*
......@@ -10,9 +10,6 @@ directory as a loopback:
./example/main -debug -threaded=false mountpoint /some/other/directory &
(cd mountpoint ; ls)
on my machine, compiles over loopback (threaded, without debug) are
about 2x slower compared to normal compiles.
Tested on:
- x86 32bits (Fedora 14).
......@@ -21,7 +18,22 @@ Tested on:
LICENSE
Like Go, this library is distributed under the new BSD. See accompanying LICENSE file.
Like Go, this library is distributed under the new BSD license. See
accompanying LICENSE file.
BENCHMARKS
The speed of go-fuse is close to libfuse's speed (measurements on my
lenovo T60 laptop):
* 'find' in tree with 14k files. fs access: 0.06s, go-fuse: 3.5s, bbfs: 3.9
* 'ls -lR' in same tree: fs access: 0.5s, go-fuse: 9.5s, bbfs: 8.8s
* copying a 100 mb file: fs access: 200mb/s, go-fuse: 182mb/s, bbfs: 190mb/s
bbfs is a loopback filesystem written in C, see
http://www.cs.nmsu.edu/~pfeiffer/fuse-tutorial.tgz
CREDITS
......
......@@ -23,9 +23,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
}
......@@ -96,10 +96,10 @@ func getFuseConn(local *os.File) (f *os.File, err os.Error) {
var data [4]byte
control := make([]byte, 4*256)
// n, oobn, recvflags - todo: error checking.
_, oobn, _,
// n, oobn, recvflags, from, errno - todo: error checking.
_, oobn, _, _,
errno := syscall.Recvmsg(
local.Fd(), data[:], control[:], nil, 0)
local.Fd(), data[:], control[:], 0)
if errno != 0 {
return
}
......
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