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

Move LoopbackFileSystem into core go-fuse library.

parent c0b9bca3
......@@ -2,7 +2,6 @@ package main
import (
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/examplelib"
"fmt"
"os"
"expvar"
......@@ -23,7 +22,7 @@ func main() {
}
orig := flag.Arg(0)
fs := examplelib.NewLoopbackFileSystem(orig)
fs := fuse.NewLoopbackFileSystem(orig)
conn := fuse.NewPathFileSystemConnector(fs)
state := fuse.NewMountState(conn)
state.Debug = *debug
......
......@@ -5,8 +5,7 @@ TARG=github.com/hanwen/go-fuse/examplelib
DEPS=../fuse
GOFILES=loopback.go \
stackfs.go \
GOFILES=stackfs.go \
zipfs.go \
multizip.go \
misc.go
......
......@@ -41,8 +41,8 @@ func (me *stackFsTestCase) Setup(t *testing.T) {
os.Mkdir(me.origDir2, 0700)
os.Mkdir(me.mountDir, 0700)
fs1 := fuse.NewPathFileSystemConnector(NewLoopbackFileSystem(me.origDir1))
fs2 := fuse.NewPathFileSystemConnector(NewLoopbackFileSystem(me.origDir2))
fs1 := fuse.NewPathFileSystemConnector(fuse.NewLoopbackFileSystem(me.origDir1))
fs2 := fuse.NewPathFileSystemConnector(fuse.NewLoopbackFileSystem(me.origDir2))
me.fs = NewSubmountFileSystem()
......@@ -154,7 +154,7 @@ func (me *stackFsTestCase) testAddRemove() {
Mode: 0755,
}
conn := fuse.NewPathFileSystemConnector(NewLoopbackFileSystem(me.origDir1))
conn := fuse.NewPathFileSystemConnector(fuse.NewLoopbackFileSystem(me.origDir1))
ok := me.fs.AddFileSystem("sub1", conn, attr)
if ok {
me.tester.Errorf("AddFileSystem should fail")
......
......@@ -12,7 +12,8 @@ GOFILES=misc.go\
pathfilesystem.go \
bufferpool.go \
default.go \
datafile.go
datafile.go \
loopback.go
include $(GOROOT)/src/Make.pkg
......@@ -2,10 +2,9 @@
// system. Its main purpose is to provide test coverage without
// having to build an actual synthetic filesystem.
package examplelib
package fuse
import (
"github.com/hanwen/go-fuse/fuse"
"fmt"
"os"
"path"
......@@ -17,7 +16,7 @@ var _ = fmt.Println
type LoopbackFileSystem struct {
root string
fuse.DefaultPathFilesystem
DefaultPathFilesystem
}
func NewLoopbackFileSystem(root string) (out *LoopbackFileSystem) {
......@@ -31,32 +30,32 @@ func (me *LoopbackFileSystem) GetPath(relPath string) string {
return path.Join(me.root, relPath)
}
func (me *LoopbackFileSystem) GetAttr(name string) (*fuse.Attr, fuse.Status) {
func (me *LoopbackFileSystem) GetAttr(name string) (*Attr, Status) {
fullPath := me.GetPath(name)
fi, err := os.Lstat(fullPath)
if err != nil {
return nil, fuse.ENOENT
return nil, ENOENT
}
out := new(fuse.Attr)
fuse.CopyFileInfo(fi, out)
out := new(Attr)
CopyFileInfo(fi, out)
return out, fuse.OK
return out, OK
}
func (me *LoopbackFileSystem) OpenDir(name string) (stream chan fuse.DirEntry, status fuse.Status) {
func (me *LoopbackFileSystem) OpenDir(name string) (stream chan DirEntry, status Status) {
// What other ways beyond O_RDONLY are there to open
// directories?
f, err := os.Open(me.GetPath(name), os.O_RDONLY, 0)
if err != nil {
return nil, fuse.OsErrorToFuseError(err)
return nil, OsErrorToFuseError(err)
}
output := make(chan fuse.DirEntry, 500)
output := make(chan DirEntry, 500)
go func() {
for {
want := 500
infos, err := f.Readdir(want)
for i, _ := range infos {
output <- fuse.DirEntry{
output <- DirEntry{
Name: infos[i].Name,
Mode: infos[i].Mode,
}
......@@ -69,82 +68,82 @@ func (me *LoopbackFileSystem) OpenDir(name string) (stream chan fuse.DirEntry, s
break
}
}
output <- fuse.DirEntry{}
output <- DirEntry{}
f.Close()
}()
return output, fuse.OK
return output, OK
}
func (me *LoopbackFileSystem) Open(name string, flags uint32) (fuseFile fuse.RawFuseFile, status fuse.Status) {
func (me *LoopbackFileSystem) Open(name string, flags uint32) (fuseFile RawFuseFile, status Status) {
f, err := os.Open(me.GetPath(name), int(flags), 0)
if err != nil {
return nil, fuse.OsErrorToFuseError(err)
return nil, OsErrorToFuseError(err)
}
return &LoopbackFile{file: f}, fuse.OK
return &LoopbackFile{file: f}, OK
}
func (me *LoopbackFileSystem) Chmod(path string, mode uint32) (code fuse.Status) {
func (me *LoopbackFileSystem) Chmod(path string, mode uint32) (code Status) {
err := os.Chmod(me.GetPath(path), mode)
return fuse.OsErrorToFuseError(err)
return OsErrorToFuseError(err)
}
func (me *LoopbackFileSystem) Chown(path string, uid uint32, gid uint32) (code fuse.Status) {
return fuse.OsErrorToFuseError(os.Chown(me.GetPath(path), int(uid), int(gid)))
func (me *LoopbackFileSystem) Chown(path string, uid uint32, gid uint32) (code Status) {
return OsErrorToFuseError(os.Chown(me.GetPath(path), int(uid), int(gid)))
}
func (me *LoopbackFileSystem) Truncate(path string, offset uint64) (code fuse.Status) {
return fuse.OsErrorToFuseError(os.Truncate(me.GetPath(path), int64(offset)))
func (me *LoopbackFileSystem) Truncate(path string, offset uint64) (code Status) {
return OsErrorToFuseError(os.Truncate(me.GetPath(path), int64(offset)))
}
func (me *LoopbackFileSystem) Utimens(path string, AtimeNs uint64, MtimeNs uint64) (code fuse.Status) {
return fuse.OsErrorToFuseError(os.Chtimes(me.GetPath(path), int64(AtimeNs), int64(MtimeNs)))
func (me *LoopbackFileSystem) Utimens(path string, AtimeNs uint64, MtimeNs uint64) (code Status) {
return OsErrorToFuseError(os.Chtimes(me.GetPath(path), int64(AtimeNs), int64(MtimeNs)))
}
func (me *LoopbackFileSystem) Readlink(name string) (out string, code fuse.Status) {
func (me *LoopbackFileSystem) Readlink(name string) (out string, code Status) {
f, err := os.Readlink(me.GetPath(name))
return f, fuse.OsErrorToFuseError(err)
return f, OsErrorToFuseError(err)
}
func (me *LoopbackFileSystem) Mknod(name string, mode uint32, dev uint32) (code fuse.Status) {
return fuse.Status(syscall.Mknod(me.GetPath(name), mode, int(dev)))
func (me *LoopbackFileSystem) Mknod(name string, mode uint32, dev uint32) (code Status) {
return Status(syscall.Mknod(me.GetPath(name), mode, int(dev)))
}
func (me *LoopbackFileSystem) Mkdir(path string, mode uint32) (code fuse.Status) {
return fuse.OsErrorToFuseError(os.Mkdir(me.GetPath(path), mode))
func (me *LoopbackFileSystem) Mkdir(path string, mode uint32) (code Status) {
return OsErrorToFuseError(os.Mkdir(me.GetPath(path), mode))
}
func (me *LoopbackFileSystem) Unlink(name string) (code fuse.Status) {
return fuse.OsErrorToFuseError(os.Remove(me.GetPath(name)))
func (me *LoopbackFileSystem) Unlink(name string) (code Status) {
return OsErrorToFuseError(os.Remove(me.GetPath(name)))
}
func (me *LoopbackFileSystem) Rmdir(name string) (code fuse.Status) {
return fuse.OsErrorToFuseError(os.Remove(me.GetPath(name)))
func (me *LoopbackFileSystem) Rmdir(name string) (code Status) {
return OsErrorToFuseError(os.Remove(me.GetPath(name)))
}
func (me *LoopbackFileSystem) Symlink(pointedTo string, linkName string) (code fuse.Status) {
return fuse.OsErrorToFuseError(os.Symlink(pointedTo, me.GetPath(linkName)))
func (me *LoopbackFileSystem) Symlink(pointedTo string, linkName string) (code Status) {
return OsErrorToFuseError(os.Symlink(pointedTo, me.GetPath(linkName)))
}
func (me *LoopbackFileSystem) Rename(oldPath string, newPath string) (code fuse.Status) {
func (me *LoopbackFileSystem) Rename(oldPath string, newPath string) (code Status) {
err := os.Rename(me.GetPath(oldPath), me.GetPath(newPath))
return fuse.OsErrorToFuseError(err)
return OsErrorToFuseError(err)
}
func (me *LoopbackFileSystem) Link(orig string, newName string) (code fuse.Status) {
return fuse.OsErrorToFuseError(os.Link(me.GetPath(orig), me.GetPath(newName)))
func (me *LoopbackFileSystem) Link(orig string, newName string) (code Status) {
return OsErrorToFuseError(os.Link(me.GetPath(orig), me.GetPath(newName)))
}
func (me *LoopbackFileSystem) Access(name string, mode uint32) (code fuse.Status) {
return fuse.Status(syscall.Access(me.GetPath(name), mode))
func (me *LoopbackFileSystem) Access(name string, mode uint32) (code Status) {
return Status(syscall.Access(me.GetPath(name), mode))
}
func (me *LoopbackFileSystem) Create(path string, flags uint32, mode uint32) (fuseFile fuse.RawFuseFile, code fuse.Status) {
func (me *LoopbackFileSystem) Create(path string, flags uint32, mode uint32) (fuseFile RawFuseFile, code Status) {
f, err := os.Open(me.GetPath(path), int(flags)|os.O_CREAT, mode)
return &LoopbackFile{file: f}, fuse.OsErrorToFuseError(err)
return &LoopbackFile{file: f}, OsErrorToFuseError(err)
}
func (me *LoopbackFileSystem) SetOptions(options *fuse.PathFileSystemConnectorOptions) {
func (me *LoopbackFileSystem) SetOptions(options *PathFileSystemConnectorOptions) {
options.NegativeTimeout = 100.0
options.AttrTimeout = 100.0
options.EntryTimeout = 100.0
......@@ -155,29 +154,29 @@ func (me *LoopbackFileSystem) SetOptions(options *fuse.PathFileSystemConnectorOp
type LoopbackFile struct {
file *os.File
fuse.DefaultRawFuseFile
DefaultRawFuseFile
}
func (me *LoopbackFile) Read(input *fuse.ReadIn, buffers *fuse.BufferPool) ([]byte, fuse.Status) {
func (me *LoopbackFile) Read(input *ReadIn, buffers *BufferPool) ([]byte, Status) {
slice := buffers.AllocBuffer(input.Size)
n, err := me.file.ReadAt(slice, int64(input.Offset))
if err == os.EOF {
// TODO - how to signal EOF?
return slice[:n], fuse.OK
return slice[:n], OK
}
return slice[:n], fuse.OsErrorToFuseError(err)
return slice[:n], OsErrorToFuseError(err)
}
func (me *LoopbackFile) Write(input *fuse.WriteIn, data []byte) (uint32, fuse.Status) {
func (me *LoopbackFile) Write(input *WriteIn, data []byte) (uint32, Status) {
n, err := me.file.WriteAt(data, int64(input.Offset))
return uint32(n), fuse.OsErrorToFuseError(err)
return uint32(n), OsErrorToFuseError(err)
}
func (me *LoopbackFile) Release() {
me.file.Close()
}
func (me *LoopbackFile) Fsync(*fuse.FsyncIn) (code fuse.Status) {
return fuse.Status(syscall.Fsync(me.file.Fd()))
func (me *LoopbackFile) Fsync(*FsyncIn) (code Status) {
return Status(syscall.Fsync(me.file.Fd()))
}
package examplelib
package fuse
import (
"github.com/hanwen/go-fuse/fuse"
"bytes"
"fmt"
"log"
......@@ -33,8 +32,8 @@ type testCase struct {
origSubdir string
origSubfile string
tester *testing.T
state *fuse.MountState
connector *fuse.PathFileSystemConnector
state *MountState
connector *PathFileSystemConnector
}
// Create and mount filesystem.
......@@ -44,8 +43,8 @@ func (me *testCase) Setup(t *testing.T) {
const name string = "hello.txt"
const subdir string = "subdir"
me.origDir = fuse.MakeTempDir()
me.mountPoint = fuse.MakeTempDir()
me.origDir = MakeTempDir()
me.mountPoint = MakeTempDir()
me.mountFile = path.Join(me.mountPoint, name)
me.mountSubdir = path.Join(me.mountPoint, subdir)
......@@ -55,9 +54,9 @@ func (me *testCase) Setup(t *testing.T) {
me.origSubfile = path.Join(me.origSubdir, "subfile")
pfs := NewLoopbackFileSystem(me.origDir)
me.connector = fuse.NewPathFileSystemConnector(pfs)
me.connector = NewPathFileSystemConnector(pfs)
me.connector.Debug = true
me.state = fuse.NewMountState(me.connector)
me.state = NewMountState(me.connector)
me.state.Mount(me.mountPoint)
//me.state.Debug = false
......@@ -272,10 +271,12 @@ func (me *testCase) testRename() {
err := os.Rename(me.mountFile, me.mountSubfile)
CheckSuccess(err)
if FileExists(me.origFile) {
f, _ := os.Lstat(me.origFile)
if f != nil {
me.tester.Errorf("original %v still exists.", me.origFile)
}
if !FileExists(me.origSubfile) {
f, _ = os.Lstat(me.origSubfile)
if f == nil {
me.tester.Errorf("destination %v does not exist.", me.origSubfile)
}
......@@ -532,7 +533,7 @@ func TestRecursiveMount(t *testing.T) {
pfs2 := NewLoopbackFileSystem(ts.origDir)
code := ts.connector.Mount("/hello.txt", pfs2)
if code != fuse.EINVAL {
if code != EINVAL {
t.Error("expect EINVAL", code)
}
......@@ -540,7 +541,7 @@ func TestRecursiveMount(t *testing.T) {
err = os.Mkdir(submnt, 0777)
CheckSuccess(err)
code = ts.connector.Mount("/mnt", pfs2)
if code != fuse.OK {
if code != OK {
t.Errorf("mkdir")
}
......@@ -552,17 +553,17 @@ func TestRecursiveMount(t *testing.T) {
f, err = os.Open(path.Join(submnt, "hello.txt"), os.O_RDONLY, 0)
CheckSuccess(err)
code = ts.connector.Unmount("/mnt")
if code != fuse.EBUSY {
if code != EBUSY {
t.Error("expect EBUSY")
}
f.Close()
// The close takes some time to propagate through FUSE.
// The close takes some time to propagate through
time.Sleep(1e9)
code = ts.connector.Unmount("/mnt")
if code != fuse.OK {
if code != OK {
t.Error("umount failed.", code)
}
......
......@@ -295,3 +295,11 @@ func NegativeEntry(time float64) *EntryOut {
func ModeToType(mode uint32) uint32 {
return (mode & 0170000) >> 12
}
func CheckSuccess(e os.Error) {
if e != nil {
panic(fmt.Sprintf("Unexpected error: %v", e))
}
}
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