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

Move path filesystems to a separate package.

Callers can apply the following gofmt rules:

gofmt -w -r 'fuse.NewPathNodeFs -> pathfs.NewPathNodeFs' $*
gofmt -w -r 'fuse.FileSystem -> pathfs.FileSystem' $*
gofmt -w -r 'fuse.LoopbackFileSystem -> pathfs.LoopbackFileSystem' $*
gofmt -w -r 'fuse.LockingFileSystem -> pathfs.LockingFileSystem' $*
gofmt -w -r 'fuse.PathNodeFs -> pathfs.PathNodeFs' $*
gofmt -w -r 'fuse.PathNodeFsOptions -> pathfs.PathNodeFsOptions' $*
gofmt -w -r 'fuse.DefaultFileSystem -> pathfs.DefaultFileSystem' $*
gofmt -w -r 'fuse.NewLoopbackFileSystem -> pathfs.NewLoopbackFileSystem' $*
gofmt -w -r 'fuse.NewLockingFileSystem -> pathfs.NewLockingFileSystem' $*
gofmt -w -r 'fuse.CopyFile -> pathfs.CopyFile' $*
parent a393c5e2
......@@ -4,7 +4,7 @@ set -eux
sh genversion.sh fuse/version.gen.go
for target in "clean" "install" ; do
for d in raw fuse benchmark zipfs unionfs \
for d in raw fuse zipfs unionfs \
example/hello example/loopback example/zipfs \
example/multizip example/unionfs \
example/autounionfs ; \
......
......@@ -14,14 +14,14 @@ import (
"time"
)
func setupFs(fs fuse.FileSystem) (string, func()) {
func setupFs(fs pathfs.FileSystem) (string, func()) {
opts := &fuse.FileSystemOptions{
EntryTimeout: 0.0,
AttrTimeout: 0.0,
NegativeTimeout: 0.0,
}
mountPoint, _ := ioutil.TempDir("", "stat_test")
nfs := fuse.NewPathNodeFs(fs, nil)
nfs := pathfs.NewPathNodeFs(fs, nil)
state, _, err := fuse.MountNodeFileSystem(mountPoint, nfs, opts)
if err != nil {
panic(fmt.Sprintf("cannot mount %v", err)) // ugh - benchmark has no error methods.
......
package benchmark
import (
"github.com/hanwen/go-fuse/fuse"
"path/filepath"
"strings"
"time"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
)
var delay = 0 * time.Microsecond
type StatFs struct {
fuse.DefaultFileSystem
pathfs.DefaultFileSystem
entries map[string]*fuse.Attr
dirs map[string][]fuse.DirEntry
delay time.Duration
......
......@@ -3,10 +3,12 @@ package main
import (
"flag"
"fmt"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/unionfs"
"os"
"time"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
"github.com/hanwen/go-fuse/unionfs"
)
func main() {
......@@ -48,7 +50,7 @@ func main() {
Owner: fuse.CurrentOwner(),
},
UpdateOnMount: true,
PathNodeFsOptions: fuse.PathNodeFsOptions{
PathNodeFsOptions: pathfs.PathNodeFsOptions{
ClientInodes: *hardlinks,
},
HideReadonly: *hide_readonly_link,
......@@ -58,7 +60,7 @@ func main() {
}
fmt.Printf("AutoUnionFs - Go-FUSE Version %v.\n", fuse.Version())
gofs := unionfs.NewAutoUnionFs(flag.Arg(1), options)
pathfs := fuse.NewPathNodeFs(gofs, nil)
pathfs := pathfs.NewPathNodeFs(gofs, nil)
state, conn, err := fuse.MountNodeFileSystem(flag.Arg(0), pathfs, &fsOpts)
if err != nil {
fmt.Printf("Mount fail: %v\n", err)
......
......@@ -4,12 +4,14 @@ package main
import (
"flag"
"github.com/hanwen/go-fuse/fuse"
"log"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
)
type HelloFs struct {
fuse.DefaultFileSystem
pathfs.DefaultFileSystem
}
func (me *HelloFs) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Status) {
......@@ -49,7 +51,7 @@ func main() {
if len(flag.Args()) < 1 {
log.Fatal("Usage:\n hello MOUNTPOINT")
}
nfs := fuse.NewPathNodeFs(&HelloFs{}, nil)
nfs := pathfs.NewPathNodeFs(&HelloFs{}, nil)
state, _, err := fuse.MountNodeFileSystem(flag.Arg(0), nfs, nil)
if err != nil {
log.Fatal("Mount fail: %v\n", err)
......
......@@ -6,11 +6,13 @@ package main
import (
"flag"
"fmt"
"github.com/hanwen/go-fuse/fuse"
"log"
"os"
"runtime"
"time"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
)
var _ = runtime.GOMAXPROCS
......@@ -27,9 +29,9 @@ func main() {
os.Exit(2)
}
var finalFs fuse.FileSystem
var finalFs pathfs.FileSystem
orig := flag.Arg(1)
loopbackfs := fuse.NewLoopbackFileSystem(orig)
loopbackfs := pathfs.NewLoopbackFileSystem(orig)
finalFs = loopbackfs
opts := &fuse.FileSystemOptions{
......@@ -39,7 +41,7 @@ func main() {
AttrTimeout: time.Second,
EntryTimeout: time.Second,
}
pathFs := fuse.NewPathNodeFs(finalFs, nil)
pathFs := pathfs.NewPathNodeFs(finalFs, nil)
conn := fuse.NewFileSystemConnector(pathFs, opts)
state := fuse.NewMountState(conn)
state.Debug = *debug
......
......@@ -3,11 +3,13 @@ package main
import (
"flag"
"fmt"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/zipfs"
"log"
"os"
"path/filepath"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
"github.com/hanwen/go-fuse/zipfs"
)
var _ = log.Printf
......@@ -23,7 +25,7 @@ func main() {
}
fs := zipfs.NewMultiZipFs()
nfs := fuse.NewPathNodeFs(fs, nil)
nfs := pathfs.NewPathNodeFs(fs, nil)
state, _, err := fuse.MountNodeFileSystem(flag.Arg(0), nfs, nil)
if err != nil {
fmt.Printf("Mount fail: %v\n", err)
......
......@@ -3,11 +3,13 @@ package main
import (
"flag"
"fmt"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/unionfs"
"log"
"os"
"time"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
"github.com/hanwen/go-fuse/unionfs"
)
func main() {
......@@ -39,7 +41,7 @@ func main() {
log.Fatal("Cannot create UnionFs", err)
os.Exit(1)
}
nodeFs := fuse.NewPathNodeFs(ufs, &fuse.PathNodeFsOptions{ClientInodes: true})
nodeFs := pathfs.NewPathNodeFs(ufs, &pathfs.PathNodeFsOptions{ClientInodes: true})
mOpts := fuse.FileSystemOptions{
EntryTimeout: time.Duration(*entry_ttl * float64(time.Second)),
AttrTimeout: time.Duration(*entry_ttl * float64(time.Second)),
......
......@@ -93,73 +93,6 @@ type FsNode interface {
StatFs() *StatfsOut
}
// A filesystem API that uses paths rather than inodes. A minimal
// file system should have at least a functional GetAttr method.
// Typically, each call happens in its own goroutine, so take care to
// make the file system thread-safe.
//
// Include DefaultFileSystem to provide a default null implementation of
// required methods.
type FileSystem interface {
// Used for pretty printing.
String() string
// Attributes. This function is the main entry point, through
// which FUSE discovers which files and directories exist.
//
// If the filesystem wants to implement hard-links, it should
// return consistent non-zero FileInfo.Ino data. Using
// hardlinks incurs a performance hit.
GetAttr(name string, context *Context) (*Attr, Status)
// These should update the file's ctime too.
Chmod(name string, mode uint32, context *Context) (code Status)
Chown(name string, uid uint32, gid uint32, context *Context) (code Status)
Utimens(name string, Atime *time.Time, Mtime *time.Time, context *Context) (code Status)
Truncate(name string, size uint64, context *Context) (code Status)
Access(name string, mode uint32, context *Context) (code Status)
// Tree structure
Link(oldName string, newName string, context *Context) (code Status)
Mkdir(name string, mode uint32, context *Context) Status
Mknod(name string, mode uint32, dev uint32, context *Context) Status
Rename(oldName string, newName string, context *Context) (code Status)
Rmdir(name string, context *Context) (code Status)
Unlink(name string, context *Context) (code Status)
// Extended attributes.
GetXAttr(name string, attribute string, context *Context) (data []byte, code Status)
ListXAttr(name string, context *Context) (attributes []string, code Status)
RemoveXAttr(name string, attr string, context *Context) Status
SetXAttr(name string, attr string, data []byte, flags int, context *Context) Status
// Called after mount.
OnMount(nodeFs *PathNodeFs)
OnUnmount()
// File handling. If opening for writing, the file's mtime
// should be updated too.
Open(name string, flags uint32, context *Context) (file File, code Status)
Create(name string, flags uint32, mode uint32, context *Context) (file File, code Status)
// Directory handling
OpenDir(name string, context *Context) (stream []DirEntry, code Status)
// Symlinks.
Symlink(value string, linkName string, context *Context) (code Status)
Readlink(name string, context *Context) (string, Status)
StatFs(name string) *StatfsOut
}
type PathNodeFsOptions struct {
// If ClientInodes is set, use Inode returned from GetAttr to
// find hard-linked files.
ClientInodes bool
}
// A File object should be returned from FileSystem.Open and
// FileSystem.Create. Include DefaultFile into the struct to inherit
// a default null implementation.
......@@ -280,9 +213,6 @@ type MountOptions struct {
Name string
}
// DefaultFileSystem implements a FileSystem that returns ENOSYS for every operation.
type DefaultFileSystem struct{}
// DefaultFile returns ENOSYS for every operation.
type DefaultFile struct{}
......
......@@ -34,7 +34,7 @@ type FileSystemConnector struct {
// Used as the generation inodes. This must be 64-bit aligned,
// for sync/atomic on i386 to work properly.
generation uint64
DefaultRawFileSystem
Debug bool
......@@ -129,7 +129,7 @@ func (c *FileSystemConnector) lookupUpdate(node *Inode) (id uint64) {
func (c *FileSystemConnector) forgetUpdate(nodeID uint64, forgetCount int) {
if nodeID == raw.FUSE_ROOT_ID {
c.nodeFs.OnUnmount()
// We never got a lookup for root, so don't try to
// forget root.
return
......
......@@ -3,158 +3,10 @@ package fuse
import (
"fmt"
"sync"
"time"
"github.com/hanwen/go-fuse/raw"
)
// This is a wrapper that makes a FileSystem threadsafe by
// trivially locking all operations. For improved performance, you
// should probably invent do your own locking inside the file system.
type LockingFileSystem struct {
// Should be public so people reusing can access the wrapped
// FS.
FS FileSystem
lock sync.Mutex
}
var _ = ((FileSystem)((*LockingFileSystem)(nil)))
func NewLockingFileSystem(pfs FileSystem) *LockingFileSystem {
l := new(LockingFileSystem)
l.FS = pfs
return l
}
func (fs *LockingFileSystem) String() string {
defer fs.locked()()
return fs.FS.String()
}
func (fs *LockingFileSystem) StatFs(name string) *StatfsOut {
defer fs.locked()()
return fs.FS.StatFs(name)
}
func (fs *LockingFileSystem) locked() func() {
fs.lock.Lock()
return func() { fs.lock.Unlock() }
}
func (fs *LockingFileSystem) GetAttr(name string, context *Context) (*Attr, Status) {
defer fs.locked()()
return fs.FS.GetAttr(name, context)
}
func (fs *LockingFileSystem) Readlink(name string, context *Context) (string, Status) {
defer fs.locked()()
return fs.FS.Readlink(name, context)
}
func (fs *LockingFileSystem) Mknod(name string, mode uint32, dev uint32, context *Context) Status {
defer fs.locked()()
return fs.FS.Mknod(name, mode, dev, context)
}
func (fs *LockingFileSystem) Mkdir(name string, mode uint32, context *Context) Status {
defer fs.locked()()
return fs.FS.Mkdir(name, mode, context)
}
func (fs *LockingFileSystem) Unlink(name string, context *Context) (code Status) {
defer fs.locked()()
return fs.FS.Unlink(name, context)
}
func (fs *LockingFileSystem) Rmdir(name string, context *Context) (code Status) {
defer fs.locked()()
return fs.FS.Rmdir(name, context)
}
func (fs *LockingFileSystem) Symlink(value string, linkName string, context *Context) (code Status) {
defer fs.locked()()
return fs.FS.Symlink(value, linkName, context)
}
func (fs *LockingFileSystem) Rename(oldName string, newName string, context *Context) (code Status) {
defer fs.locked()()
return fs.FS.Rename(oldName, newName, context)
}
func (fs *LockingFileSystem) Link(oldName string, newName string, context *Context) (code Status) {
defer fs.locked()()
return fs.FS.Link(oldName, newName, context)
}
func (fs *LockingFileSystem) Chmod(name string, mode uint32, context *Context) (code Status) {
defer fs.locked()()
return fs.FS.Chmod(name, mode, context)
}
func (fs *LockingFileSystem) Chown(name string, uid uint32, gid uint32, context *Context) (code Status) {
defer fs.locked()()
return fs.FS.Chown(name, uid, gid, context)
}
func (fs *LockingFileSystem) Truncate(name string, offset uint64, context *Context) (code Status) {
defer fs.locked()()
return fs.FS.Truncate(name, offset, context)
}
func (fs *LockingFileSystem) Open(name string, flags uint32, context *Context) (file File, code Status) {
return fs.FS.Open(name, flags, context)
}
func (fs *LockingFileSystem) OpenDir(name string, context *Context) (stream []DirEntry, status Status) {
defer fs.locked()()
return fs.FS.OpenDir(name, context)
}
func (fs *LockingFileSystem) OnMount(nodeFs *PathNodeFs) {
defer fs.locked()()
fs.FS.OnMount(nodeFs)
}
func (fs *LockingFileSystem) OnUnmount() {
defer fs.locked()()
fs.FS.OnUnmount()
}
func (fs *LockingFileSystem) Access(name string, mode uint32, context *Context) (code Status) {
defer fs.locked()()
return fs.FS.Access(name, mode, context)
}
func (fs *LockingFileSystem) Create(name string, flags uint32, mode uint32, context *Context) (file File, code Status) {
defer fs.locked()()
return fs.FS.Create(name, flags, mode, context)
}
func (fs *LockingFileSystem) Utimens(name string, Atime *time.Time, Mtime *time.Time, context *Context) (code Status) {
defer fs.locked()()
return fs.FS.Utimens(name, Atime, Mtime, context)
}
func (fs *LockingFileSystem) GetXAttr(name string, attr string, context *Context) ([]byte, Status) {
defer fs.locked()()
return fs.FS.GetXAttr(name, attr, context)
}
func (fs *LockingFileSystem) SetXAttr(name string, attr string, data []byte, flags int, context *Context) Status {
defer fs.locked()()
return fs.FS.SetXAttr(name, attr, data, flags, context)
}
func (fs *LockingFileSystem) ListXAttr(name string, context *Context) ([]string, Status) {
defer fs.locked()()
return fs.FS.ListXAttr(name, context)
}
func (fs *LockingFileSystem) RemoveXAttr(name string, attr string, context *Context) Status {
defer fs.locked()()
return fs.FS.RemoveXAttr(name, attr, context)
}
////////////////////////////////////////////////////////////////
// Locking raw FS.
......
......@@ -175,7 +175,7 @@ func (ms *MountState) Unmount() (err error) {
time.Sleep(delay)
}
if err != nil {
return
return
}
// Wait for event loops to exit.
ms.loops.Wait()
......
package pathfs
import (
"time"
"github.com/hanwen/go-fuse/fuse"
)
// A filesystem API that uses paths rather than inodes. A minimal
// file system should have at least a functional GetAttr method.
// Typically, each call happens in its own goroutine, so take care to
// make the file system thread-safe.
//
// Include DefaultFileSystem to provide a default null implementation of
// required methods.
type FileSystem interface {
// Used for pretty printing.
String() string
// Attributes. This function is the main entry point, through
// which FUSE discovers which files and directories exist.
//
// If the filesystem wants to implement hard-links, it should
// return consistent non-zero FileInfo.Ino data. Using
// hardlinks incurs a performance hit.
GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Status)
// These should update the file's ctime too.
Chmod(name string, mode uint32, context *fuse.Context) (code fuse.Status)
Chown(name string, uid uint32, gid uint32, context *fuse.Context) (code fuse.Status)
Utimens(name string, Atime *time.Time, Mtime *time.Time, context *fuse.Context) (code fuse.Status)
Truncate(name string, size uint64, context *fuse.Context) (code fuse.Status)
Access(name string, mode uint32, context *fuse.Context) (code fuse.Status)
// Tree structure
Link(oldName string, newName string, context *fuse.Context) (code fuse.Status)
Mkdir(name string, mode uint32, context *fuse.Context) fuse.Status
Mknod(name string, mode uint32, dev uint32, context *fuse.Context) fuse.Status
Rename(oldName string, newName string, context *fuse.Context) (code fuse.Status)
Rmdir(name string, context *fuse.Context) (code fuse.Status)
Unlink(name string, context *fuse.Context) (code fuse.Status)
// Extended attributes.
GetXAttr(name string, attribute string, context *fuse.Context) (data []byte, code fuse.Status)
ListXAttr(name string, context *fuse.Context) (attributes []string, code fuse.Status)
RemoveXAttr(name string, attr string, context *fuse.Context) fuse.Status
SetXAttr(name string, attr string, data []byte, flags int, context *fuse.Context) fuse.Status
// Called after mount.
OnMount(nodeFs *PathNodeFs)
OnUnmount()
// File handling. If opening for writing, the file's mtime
// should be updated too.
Open(name string, flags uint32, context *fuse.Context) (file fuse.File, code fuse.Status)
Create(name string, flags uint32, mode uint32, context *fuse.Context) (file fuse.File, code fuse.Status)
// Directory handling
OpenDir(name string, context *fuse.Context) (stream []fuse.DirEntry, code fuse.Status)
// Symlinks.
Symlink(value string, linkName string, context *fuse.Context) (code fuse.Status)
Readlink(name string, context *fuse.Context) (string, fuse.Status)
StatFs(name string) *fuse.StatfsOut
}
type PathNodeFsOptions struct {
// If ClientInodes is set, use Inode returned from GetAttr to
// find hard-linked files.
ClientInodes bool
}
package fuse
package pathfs
import (
"os"
"github.com/hanwen/go-fuse/fuse"
)
func CopyFile(srcFs, destFs FileSystem, srcFile, destFile string, context *Context) Status {
func CopyFile(srcFs, destFs FileSystem, srcFile, destFile string, context *fuse.Context) fuse.Status {
src, code := srcFs.Open(srcFile, uint32(os.O_RDONLY), context)
if !code.Ok() {
return code
......@@ -44,12 +46,12 @@ func CopyFile(srcFs, destFs FileSystem, srcFile, destFile string, context *Conte
return code
}
if int(n) < len(data) {
return EIO
return fuse.EIO
}
if len(data) < len(buf) {
break
}
off += int64(len(data))
}
return OK
return fuse.OK
}
package fuse
package pathfs
import (
"io/ioutil"
......
package fuse
package pathfs
import (
"time"
"github.com/hanwen/go-fuse/fuse"
)
var _ = FileSystem((*DefaultFileSystem)(nil))
// DefaultFileSystem implements a FileSystem that returns ENOSYS for every operation.
type DefaultFileSystem struct{}
// DefaultFileSystem
func (fs *DefaultFileSystem) GetAttr(name string, context *Context) (*Attr, Status) {
return nil, ENOSYS
func (fs *DefaultFileSystem) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Status) {
return nil, fuse.ENOSYS
}
func (fs *DefaultFileSystem) GetXAttr(name string, attr string, context *Context) ([]byte, Status) {
return nil, ENOSYS
func (fs *DefaultFileSystem) GetXAttr(name string, attr string, context *fuse.Context) ([]byte, fuse.Status) {
return nil, fuse.ENOSYS
}
func (fs *DefaultFileSystem) SetXAttr(name string, attr string, data []byte, flags int, context *Context) Status {
return ENOSYS
func (fs *DefaultFileSystem) SetXAttr(name string, attr string, data []byte, flags int, context *fuse.Context) fuse.Status {
return fuse.ENOSYS
}
func (fs *DefaultFileSystem) ListXAttr(name string, context *Context) ([]string, Status) {
return nil, ENOSYS
func (fs *DefaultFileSystem) ListXAttr(name string, context *fuse.Context) ([]string, fuse.Status) {
return nil, fuse.ENOSYS
}
func (fs *DefaultFileSystem) RemoveXAttr(name string, attr string, context *Context) Status {
return ENOSYS
func (fs *DefaultFileSystem) RemoveXAttr(name string, attr string, context *fuse.Context) fuse.Status {
return fuse.ENOSYS
}
func (fs *DefaultFileSystem) Readlink(name string, context *Context) (string, Status) {
return "", ENOSYS
func (fs *DefaultFileSystem) Readlink(name string, context *fuse.Context) (string, fuse.Status) {
return "", fuse.ENOSYS
}
func (fs *DefaultFileSystem) Mknod(name string, mode uint32, dev uint32, context *Context) Status {
return ENOSYS
func (fs *DefaultFileSystem) Mknod(name string, mode uint32, dev uint32, context *fuse.Context) fuse.Status {
return fuse.ENOSYS
}
func (fs *DefaultFileSystem) Mkdir(name string, mode uint32, context *Context) Status {
return ENOSYS
func (fs *DefaultFileSystem) Mkdir(name string, mode uint32, context *fuse.Context) fuse.Status {
return fuse.ENOSYS
}
func (fs *DefaultFileSystem) Unlink(name string, context *Context) (code Status) {
return ENOSYS
func (fs *DefaultFileSystem) Unlink(name string, context *fuse.Context) (code fuse.Status) {
return fuse.ENOSYS
}
func (fs *DefaultFileSystem) Rmdir(name string, context *Context) (code Status) {
return ENOSYS
func (fs *DefaultFileSystem) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
return fuse.ENOSYS
}
func (fs *DefaultFileSystem) Symlink(value string, linkName string, context *Context) (code Status) {
return ENOSYS
func (fs *DefaultFileSystem) Symlink(value string, linkName string, context *fuse.Context) (code fuse.Status) {
return fuse.ENOSYS
}
func (fs *DefaultFileSystem) Rename(oldName string, newName string, context *Context) (code Status) {
return ENOSYS
func (fs *DefaultFileSystem) Rename(oldName string, newName string, context *fuse.Context) (code fuse.Status) {
return fuse.ENOSYS
}
func (fs *DefaultFileSystem) Link(oldName string, newName string, context *Context) (code Status) {
return ENOSYS
func (fs *DefaultFileSystem) Link(oldName string, newName string, context *fuse.Context) (code fuse.Status) {
return fuse.ENOSYS
}
func (fs *DefaultFileSystem) Chmod(name string, mode uint32, context *Context) (code Status) {
return ENOSYS
func (fs *DefaultFileSystem) Chmod(name string, mode uint32, context *fuse.Context) (code fuse.Status) {
return fuse.ENOSYS
}
func (fs *DefaultFileSystem) Chown(name string, uid uint32, gid uint32, context *Context) (code Status) {
return ENOSYS
func (fs *DefaultFileSystem) Chown(name string, uid uint32, gid uint32, context *fuse.Context) (code fuse.Status) {
return fuse.ENOSYS
}
func (fs *DefaultFileSystem) Truncate(name string, offset uint64, context *Context) (code Status) {
return ENOSYS
func (fs *DefaultFileSystem) Truncate(name string, offset uint64, context *fuse.Context) (code fuse.Status) {
return fuse.ENOSYS
}
func (fs *DefaultFileSystem) Open(name string, flags uint32, context *Context) (file File, code Status) {
return nil, ENOSYS
func (fs *DefaultFileSystem) Open(name string, flags uint32, context *fuse.Context) (file fuse.File, code fuse.Status) {
return nil, fuse.ENOSYS
}
func (fs *DefaultFileSystem) OpenDir(name string, context *Context) (stream []DirEntry, status Status) {
return nil, ENOSYS
func (fs *DefaultFileSystem) OpenDir(name string, context *fuse.Context) (stream []fuse.DirEntry, status fuse.Status) {
return nil, fuse.ENOSYS
}
func (fs *DefaultFileSystem) OnMount(nodeFs *PathNodeFs) {
......@@ -85,22 +90,22 @@ func (fs *DefaultFileSystem) OnMount(nodeFs *PathNodeFs) {
func (fs *DefaultFileSystem) OnUnmount() {
}
func (fs *DefaultFileSystem) Access(name string, mode uint32, context *Context) (code Status) {
return ENOSYS
func (fs *DefaultFileSystem) Access(name string, mode uint32, context *fuse.Context) (code fuse.Status) {
return fuse.ENOSYS
}
func (fs *DefaultFileSystem) Create(name string, flags uint32, mode uint32, context *Context) (file File, code Status) {
return nil, ENOSYS
func (fs *DefaultFileSystem) Create(name string, flags uint32, mode uint32, context *fuse.Context) (file fuse.File, code fuse.Status) {
return nil, fuse.ENOSYS
}
func (fs *DefaultFileSystem) Utimens(name string, Atime *time.Time, Mtime *time.Time, context *Context) (code Status) {
return ENOSYS
func (fs *DefaultFileSystem) Utimens(name string, Atime *time.Time, Mtime *time.Time, context *fuse.Context) (code fuse.Status) {
return fuse.ENOSYS
}
func (fs *DefaultFileSystem) String() string {
return "DefaultFileSystem"
}
func (fs *DefaultFileSystem) StatFs(name string) *StatfsOut {
func (fs *DefaultFileSystem) StatFs(name string) *fuse.StatfsOut {
return nil
}
package pathfs
import (
"sync"
"time"
"github.com/hanwen/go-fuse/fuse"
)
// This is a wrapper that makes a FileSystem threadsafe by
// trivially locking all operations. For improved performance, you
// should probably invent do your own locking inside the file system.
type LockingFileSystem struct {
// Should be public so people reusing can access the wrapped
// FS.
FS FileSystem
lock sync.Mutex
}
var _ = ((FileSystem)((*LockingFileSystem)(nil)))
func NewLockingFileSystem(pfs FileSystem) *LockingFileSystem {
l := new(LockingFileSystem)
l.FS = pfs
return l
}
func (fs *LockingFileSystem) String() string {
defer fs.locked()()
return fs.FS.String()
}
func (fs *LockingFileSystem) StatFs(name string) *fuse.StatfsOut {
defer fs.locked()()
return fs.FS.StatFs(name)
}
func (fs *LockingFileSystem) locked() func() {
fs.lock.Lock()
return func() { fs.lock.Unlock() }
}
func (fs *LockingFileSystem) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Status) {
defer fs.locked()()
return fs.FS.GetAttr(name, context)
}
func (fs *LockingFileSystem) Readlink(name string, context *fuse.Context) (string, fuse.Status) {
defer fs.locked()()
return fs.FS.Readlink(name, context)
}
func (fs *LockingFileSystem) Mknod(name string, mode uint32, dev uint32, context *fuse.Context) fuse.Status {
defer fs.locked()()
return fs.FS.Mknod(name, mode, dev, context)
}
func (fs *LockingFileSystem) Mkdir(name string, mode uint32, context *fuse.Context) fuse.Status {
defer fs.locked()()
return fs.FS.Mkdir(name, mode, context)
}
func (fs *LockingFileSystem) Unlink(name string, context *fuse.Context) (code fuse.Status) {
defer fs.locked()()
return fs.FS.Unlink(name, context)
}
func (fs *LockingFileSystem) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
defer fs.locked()()
return fs.FS.Rmdir(name, context)
}
func (fs *LockingFileSystem) Symlink(value string, linkName string, context *fuse.Context) (code fuse.Status) {
defer fs.locked()()
return fs.FS.Symlink(value, linkName, context)
}
func (fs *LockingFileSystem) Rename(oldName string, newName string, context *fuse.Context) (code fuse.Status) {
defer fs.locked()()
return fs.FS.Rename(oldName, newName, context)
}
func (fs *LockingFileSystem) Link(oldName string, newName string, context *fuse.Context) (code fuse.Status) {
defer fs.locked()()
return fs.FS.Link(oldName, newName, context)
}
func (fs *LockingFileSystem) Chmod(name string, mode uint32, context *fuse.Context) (code fuse.Status) {
defer fs.locked()()
return fs.FS.Chmod(name, mode, context)
}
func (fs *LockingFileSystem) Chown(name string, uid uint32, gid uint32, context *fuse.Context) (code fuse.Status) {
defer fs.locked()()
return fs.FS.Chown(name, uid, gid, context)
}
func (fs *LockingFileSystem) Truncate(name string, offset uint64, context *fuse.Context) (code fuse.Status) {
defer fs.locked()()
return fs.FS.Truncate(name, offset, context)
}
func (fs *LockingFileSystem) Open(name string, flags uint32, context *fuse.Context) (file fuse.File, code fuse.Status) {
return fs.FS.Open(name, flags, context)
}
func (fs *LockingFileSystem) OpenDir(name string, context *fuse.Context) (stream []fuse.DirEntry, status fuse.Status) {
defer fs.locked()()
return fs.FS.OpenDir(name, context)
}
func (fs *LockingFileSystem) OnMount(nodeFs *PathNodeFs) {
defer fs.locked()()
fs.FS.OnMount(nodeFs)
}
func (fs *LockingFileSystem) OnUnmount() {
defer fs.locked()()
fs.FS.OnUnmount()
}
func (fs *LockingFileSystem) Access(name string, mode uint32, context *fuse.Context) (code fuse.Status) {
defer fs.locked()()
return fs.FS.Access(name, mode, context)
}
func (fs *LockingFileSystem) Create(name string, flags uint32, mode uint32, context *fuse.Context) (file fuse.File, code fuse.Status) {
defer fs.locked()()
return fs.FS.Create(name, flags, mode, context)
}
func (fs *LockingFileSystem) Utimens(name string, Atime *time.Time, Mtime *time.Time, context *fuse.Context) (code fuse.Status) {
defer fs.locked()()
return fs.FS.Utimens(name, Atime, Mtime, context)
}
func (fs *LockingFileSystem) GetXAttr(name string, attr string, context *fuse.Context) ([]byte, fuse.Status) {
defer fs.locked()()
return fs.FS.GetXAttr(name, attr, context)
}
func (fs *LockingFileSystem) SetXAttr(name string, attr string, data []byte, flags int, context *fuse.Context) fuse.Status {
defer fs.locked()()
return fs.FS.SetXAttr(name, attr, data, flags, context)
}
func (fs *LockingFileSystem) ListXAttr(name string, context *fuse.Context) ([]string, fuse.Status) {
defer fs.locked()()
return fs.FS.ListXAttr(name, context)
}
func (fs *LockingFileSystem) RemoveXAttr(name string, attr string, context *fuse.Context) fuse.Status {
defer fs.locked()()
return fs.FS.RemoveXAttr(name, attr, context)
}
package fuse
package pathfs
import (
"fmt"
......@@ -8,6 +8,8 @@ import (
"path/filepath"
"syscall"
"time"
"github.com/hanwen/go-fuse/fuse"
)
var _ = fmt.Println
......@@ -32,7 +34,7 @@ func (fs *LoopbackFileSystem) GetPath(relPath string) string {
return filepath.Join(fs.Root, relPath)
}
func (fs *LoopbackFileSystem) GetAttr(name string, context *Context) (a *Attr, code Status) {
func (fs *LoopbackFileSystem) GetAttr(name string, context *fuse.Context) (a *fuse.Attr, code fuse.Status) {
fullPath := fs.GetPath(name)
var err error = nil
st := syscall.Stat_t{}
......@@ -45,32 +47,32 @@ func (fs *LoopbackFileSystem) GetAttr(name string, context *Context) (a *Attr, c
}
if err != nil {
return nil, ToStatus(err)
return nil, fuse.ToStatus(err)
}
a = &Attr{}
a = &fuse.Attr{}
a.FromStat(&st)
return a, OK
return a, fuse.OK
}
var _ = (FileSystem)((*LoopbackFileSystem)(nil))
func (fs *LoopbackFileSystem) OpenDir(name string, context *Context) (stream []DirEntry, status Status) {
func (fs *LoopbackFileSystem) OpenDir(name string, context *fuse.Context) (stream []fuse.DirEntry, status fuse.Status) {
// What other ways beyond O_RDONLY are there to open
// directories?
f, err := os.Open(fs.GetPath(name))
if err != nil {
return nil, ToStatus(err)
return nil, fuse.ToStatus(err)
}
want := 500
output := make([]DirEntry, 0, want)
output := make([]fuse.DirEntry, 0, want)
for {
infos, err := f.Readdir(want)
for i := range infos {
n := infos[i].Name()
d := DirEntry{
d := fuse.DirEntry{
Name: n,
}
if s := ToStatT(infos[i]); s != nil {
if s := fuse.ToStatT(infos[i]); s != nil {
d.Mode = uint32(s.Mode)
} else {
log.Printf("ReadDir entry %q for %q has no stat info", n, name)
......@@ -87,31 +89,31 @@ func (fs *LoopbackFileSystem) OpenDir(name string, context *Context) (stream []D
}
f.Close()
return output, OK
return output, fuse.OK
}
func (fs *LoopbackFileSystem) Open(name string, flags uint32, context *Context) (fuseFile File, status Status) {
func (fs *LoopbackFileSystem) Open(name string, flags uint32, context *fuse.Context) (fuseFile fuse.File, status fuse.Status) {
f, err := os.OpenFile(fs.GetPath(name), int(flags), 0)
if err != nil {
return nil, ToStatus(err)
return nil, fuse.ToStatus(err)
}
return &LoopbackFile{File: f}, OK
return &fuse.LoopbackFile{File: f}, fuse.OK
}
func (fs *LoopbackFileSystem) Chmod(path string, mode uint32, context *Context) (code Status) {
func (fs *LoopbackFileSystem) Chmod(path string, mode uint32, context *fuse.Context) (code fuse.Status) {
err := os.Chmod(fs.GetPath(path), os.FileMode(mode))
return ToStatus(err)
return fuse.ToStatus(err)
}
func (fs *LoopbackFileSystem) Chown(path string, uid uint32, gid uint32, context *Context) (code Status) {
return ToStatus(os.Chown(fs.GetPath(path), int(uid), int(gid)))
func (fs *LoopbackFileSystem) Chown(path string, uid uint32, gid uint32, context *fuse.Context) (code fuse.Status) {
return fuse.ToStatus(os.Chown(fs.GetPath(path), int(uid), int(gid)))
}
func (fs *LoopbackFileSystem) Truncate(path string, offset uint64, context *Context) (code Status) {
return ToStatus(os.Truncate(fs.GetPath(path), int64(offset)))
func (fs *LoopbackFileSystem) Truncate(path string, offset uint64, context *fuse.Context) (code fuse.Status) {
return fuse.ToStatus(os.Truncate(fs.GetPath(path), int64(offset)))
}
func (fs *LoopbackFileSystem) Utimens(path string, Atime *time.Time, Mtime *time.Time, context *Context) (code Status) {
func (fs *LoopbackFileSystem) Utimens(path string, Atime *time.Time, Mtime *time.Time, context *fuse.Context) (code fuse.Status) {
var a time.Time
if Atime != nil {
a = *Atime
......@@ -120,49 +122,49 @@ func (fs *LoopbackFileSystem) Utimens(path string, Atime *time.Time, Mtime *time
if Mtime != nil {
m = *Mtime
}
return ToStatus(os.Chtimes(fs.GetPath(path), a, m))
return fuse.ToStatus(os.Chtimes(fs.GetPath(path), a, m))
}
func (fs *LoopbackFileSystem) Readlink(name string, context *Context) (out string, code Status) {
func (fs *LoopbackFileSystem) Readlink(name string, context *fuse.Context) (out string, code fuse.Status) {
f, err := os.Readlink(fs.GetPath(name))
return f, ToStatus(err)
return f, fuse.ToStatus(err)
}
func (fs *LoopbackFileSystem) Mknod(name string, mode uint32, dev uint32, context *Context) (code Status) {
return ToStatus(syscall.Mknod(fs.GetPath(name), mode, int(dev)))
func (fs *LoopbackFileSystem) Mknod(name string, mode uint32, dev uint32, context *fuse.Context) (code fuse.Status) {
return fuse.ToStatus(syscall.Mknod(fs.GetPath(name), mode, int(dev)))
}
func (fs *LoopbackFileSystem) Mkdir(path string, mode uint32, context *Context) (code Status) {
return ToStatus(os.Mkdir(fs.GetPath(path), os.FileMode(mode)))
func (fs *LoopbackFileSystem) Mkdir(path string, mode uint32, context *fuse.Context) (code fuse.Status) {
return fuse.ToStatus(os.Mkdir(fs.GetPath(path), os.FileMode(mode)))
}
// Don't use os.Remove, it removes twice (unlink followed by rmdir).
func (fs *LoopbackFileSystem) Unlink(name string, context *Context) (code Status) {
return ToStatus(syscall.Unlink(fs.GetPath(name)))
func (fs *LoopbackFileSystem) Unlink(name string, context *fuse.Context) (code fuse.Status) {
return fuse.ToStatus(syscall.Unlink(fs.GetPath(name)))
}
func (fs *LoopbackFileSystem) Rmdir(name string, context *Context) (code Status) {
return ToStatus(syscall.Rmdir(fs.GetPath(name)))
func (fs *LoopbackFileSystem) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
return fuse.ToStatus(syscall.Rmdir(fs.GetPath(name)))
}
func (fs *LoopbackFileSystem) Symlink(pointedTo string, linkName string, context *Context) (code Status) {
return ToStatus(os.Symlink(pointedTo, fs.GetPath(linkName)))
func (fs *LoopbackFileSystem) Symlink(pointedTo string, linkName string, context *fuse.Context) (code fuse.Status) {
return fuse.ToStatus(os.Symlink(pointedTo, fs.GetPath(linkName)))
}
func (fs *LoopbackFileSystem) Rename(oldPath string, newPath string, context *Context) (code Status) {
func (fs *LoopbackFileSystem) Rename(oldPath string, newPath string, context *fuse.Context) (codee fuse.Status) {
err := os.Rename(fs.GetPath(oldPath), fs.GetPath(newPath))
return ToStatus(err)
return fuse.ToStatus(err)
}
func (fs *LoopbackFileSystem) Link(orig string, newName string, context *Context) (code Status) {
return ToStatus(os.Link(fs.GetPath(orig), fs.GetPath(newName)))
func (fs *LoopbackFileSystem) Link(orig string, newName string, context *fuse.Context) (code fuse.Status) {
return fuse.ToStatus(os.Link(fs.GetPath(orig), fs.GetPath(newName)))
}
func (fs *LoopbackFileSystem) Access(name string, mode uint32, context *Context) (code Status) {
return ToStatus(syscall.Access(fs.GetPath(name), mode))
func (fs *LoopbackFileSystem) Access(name string, mode uint32, context *fuse.Context) (code fuse.Status) {
return fuse.ToStatus(syscall.Access(fs.GetPath(name), mode))
}
func (fs *LoopbackFileSystem) Create(path string, flags uint32, mode uint32, context *Context) (fuseFile File, code Status) {
func (fs *LoopbackFileSystem) Create(path string, flags uint32, mode uint32, context *fuse.Context) (fuseFile fuse.File, code fuse.Status) {
f, err := os.OpenFile(fs.GetPath(path), int(flags)|os.O_CREATE, os.FileMode(mode))
return &LoopbackFile{File: f}, ToStatus(err)
return &fuse.LoopbackFile{File: f}, fuse.ToStatus(err)
}
package fuse
package pathfs
import (
"fmt"
"syscall"
"github.com/hanwen/go-fuse/fuse"
)
func (fs *LoopbackFileSystem) StatFs(name string) *StatfsOut {
func (fs *LoopbackFileSystem) StatFs(name string) *fuse.StatfsOut {
s := syscall.Statfs_t{}
err := syscall.Statfs(fs.GetPath(name), &s)
if err == nil {
return &StatfsOut{
return &fuse.StatfsOut{
Blocks: s.Blocks,
Bsize: uint32(s.Bsize),
Bfree: s.Bfree,
......@@ -23,23 +25,23 @@ func (fs *LoopbackFileSystem) StatFs(name string) *StatfsOut {
return nil
}
func (fs *LoopbackFileSystem) ListXAttr(name string, context *Context) ([]string, Status) {
func (fs *LoopbackFileSystem) ListXAttr(name string, context *fuse.Context) ([]string, fuse.Status) {
data, errNo := ListXAttr(fs.GetPath(name))
return data, Status(errNo)
return data, fuse.Status(errNo)
}
func (fs *LoopbackFileSystem) RemoveXAttr(name string, attr string, context *Context) Status {
return Status(Removexattr(fs.GetPath(name), attr))
func (fs *LoopbackFileSystem) RemoveXAttr(name string, attr string, context *fuse.Context) fuse.Status {
return fuse.Status(Removexattr(fs.GetPath(name), attr))
}
func (fs *LoopbackFileSystem) String() string {
return fmt.Sprintf("LoopbackFs(%s)", fs.Root)
}
func (fs *LoopbackFileSystem) GetXAttr(name string, attr string, context *Context) ([]byte, Status) {
func (fs *LoopbackFileSystem) GetXAttr(name string, attr string, context *fuse.Context) ([]byte, fuse.Status) {
data := make([]byte, 1024)
data, errNo := GetXAttr(fs.GetPath(name), attr, data)
return data, Status(errNo)
return data, fuse.Status(errNo)
}
package fuse
package pathfs
import (
"io/ioutil"
"os"
"syscall"
"testing"
"github.com/hanwen/go-fuse/fuse"
)
type ownerFs struct {
......@@ -13,26 +15,26 @@ type ownerFs struct {
const _RANDOM_OWNER = 31415265
func (fs *ownerFs) GetAttr(name string, context *Context) (*Attr, Status) {
func (fs *ownerFs) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Status) {
if name == "" {
return &Attr{
Mode: S_IFDIR | 0755,
}, OK
return &fuse.Attr{
Mode: fuse.S_IFDIR | 0755,
}, fuse.OK
}
a := &Attr{
Mode: S_IFREG | 0644,
a := &fuse.Attr{
Mode: fuse.S_IFREG | 0644,
}
a.Uid = _RANDOM_OWNER
a.Gid = _RANDOM_OWNER
return a, OK
return a, fuse.OK
}
func setupOwnerTest(t *testing.T, opts *FileSystemOptions) (workdir string, cleanup func()) {
func setupOwnerTest(t *testing.T, opts *fuse.FileSystemOptions) (workdir string, cleanup func()) {
wd, err := ioutil.TempDir("", "go-fuse-owner_test")
fs := &ownerFs{}
nfs := NewPathNodeFs(fs, nil)
state, _, err := MountNodeFileSystem(wd, nfs, opts)
state, _, err := fuse.MountNodeFileSystem(wd, nfs, opts)
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
}
......@@ -44,7 +46,7 @@ func setupOwnerTest(t *testing.T, opts *FileSystemOptions) (workdir string, clea
}
func TestOwnerDefault(t *testing.T) {
wd, cleanup := setupOwnerTest(t, NewFileSystemOptions())
wd, cleanup := setupOwnerTest(t, fuse.NewFileSystemOptions())
defer cleanup()
var stat syscall.Stat_t
......@@ -59,7 +61,7 @@ func TestOwnerDefault(t *testing.T) {
}
func TestOwnerRoot(t *testing.T) {
wd, cleanup := setupOwnerTest(t, &FileSystemOptions{})
wd, cleanup := setupOwnerTest(t, &fuse.FileSystemOptions{})
defer cleanup()
var st syscall.Stat_t
......@@ -74,7 +76,7 @@ func TestOwnerRoot(t *testing.T) {
}
func TestOwnerOverride(t *testing.T) {
wd, cleanup := setupOwnerTest(t, &FileSystemOptions{Owner: &Owner{42, 43}})
wd, cleanup := setupOwnerTest(t, &fuse.FileSystemOptions{Owner: &fuse.Owner{42, 43}})
defer cleanup()
var stat syscall.Stat_t
......
This diff is collapsed.
package fuse
package pathfs
import (
"fmt"
"path/filepath"
"time"
"github.com/hanwen/go-fuse/fuse"
)
// PrefixFileSystem adds a path prefix to incoming calls.
......@@ -16,59 +18,59 @@ func (fs *PrefixFileSystem) prefixed(n string) string {
return filepath.Join(fs.Prefix, n)
}
func (fs *PrefixFileSystem) GetAttr(name string, context *Context) (*Attr, Status) {
func (fs *PrefixFileSystem) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Status) {
return fs.FileSystem.GetAttr(fs.prefixed(name), context)
}
func (fs *PrefixFileSystem) Readlink(name string, context *Context) (string, Status) {
func (fs *PrefixFileSystem) Readlink(name string, context *fuse.Context) (string, fuse.Status) {
return fs.FileSystem.Readlink(fs.prefixed(name), context)
}
func (fs *PrefixFileSystem) Mknod(name string, mode uint32, dev uint32, context *Context) Status {
func (fs *PrefixFileSystem) Mknod(name string, mode uint32, dev uint32, context *fuse.Context) fuse.Status {
return fs.FileSystem.Mknod(fs.prefixed(name), mode, dev, context)
}
func (fs *PrefixFileSystem) Mkdir(name string, mode uint32, context *Context) Status {
func (fs *PrefixFileSystem) Mkdir(name string, mode uint32, context *fuse.Context) fuse.Status {
return fs.FileSystem.Mkdir(fs.prefixed(name), mode, context)
}
func (fs *PrefixFileSystem) Unlink(name string, context *Context) (code Status) {
func (fs *PrefixFileSystem) Unlink(name string, context *fuse.Context) (code fuse.Status) {
return fs.FileSystem.Unlink(fs.prefixed(name), context)
}
func (fs *PrefixFileSystem) Rmdir(name string, context *Context) (code Status) {
func (fs *PrefixFileSystem) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
return fs.FileSystem.Rmdir(fs.prefixed(name), context)
}
func (fs *PrefixFileSystem) Symlink(value string, linkName string, context *Context) (code Status) {
func (fs *PrefixFileSystem) Symlink(value string, linkName string, context *fuse.Context) (code fuse.Status) {
return fs.FileSystem.Symlink(value, fs.prefixed(linkName), context)
}
func (fs *PrefixFileSystem) Rename(oldName string, newName string, context *Context) (code Status) {
func (fs *PrefixFileSystem) Rename(oldName string, newName string, context *fuse.Context) (code fuse.Status) {
return fs.FileSystem.Rename(fs.prefixed(oldName), fs.prefixed(newName), context)
}
func (fs *PrefixFileSystem) Link(oldName string, newName string, context *Context) (code Status) {
func (fs *PrefixFileSystem) Link(oldName string, newName string, context *fuse.Context) (code fuse.Status) {
return fs.FileSystem.Link(fs.prefixed(oldName), fs.prefixed(newName), context)
}
func (fs *PrefixFileSystem) Chmod(name string, mode uint32, context *Context) (code Status) {
func (fs *PrefixFileSystem) Chmod(name string, mode uint32, context *fuse.Context) (code fuse.Status) {
return fs.FileSystem.Chmod(fs.prefixed(name), mode, context)
}
func (fs *PrefixFileSystem) Chown(name string, uid uint32, gid uint32, context *Context) (code Status) {
func (fs *PrefixFileSystem) Chown(name string, uid uint32, gid uint32, context *fuse.Context) (code fuse.Status) {
return fs.FileSystem.Chown(fs.prefixed(name), uid, gid, context)
}
func (fs *PrefixFileSystem) Truncate(name string, offset uint64, context *Context) (code Status) {
func (fs *PrefixFileSystem) Truncate(name string, offset uint64, context *fuse.Context) (code fuse.Status) {
return fs.FileSystem.Truncate(fs.prefixed(name), offset, context)
}
func (fs *PrefixFileSystem) Open(name string, flags uint32, context *Context) (file File, code Status) {
func (fs *PrefixFileSystem) Open(name string, flags uint32, context *fuse.Context) (file fuse.File, code fuse.Status) {
return fs.FileSystem.Open(fs.prefixed(name), flags, context)
}
func (fs *PrefixFileSystem) OpenDir(name string, context *Context) (stream []DirEntry, status Status) {
func (fs *PrefixFileSystem) OpenDir(name string, context *fuse.Context) (stream []fuse.DirEntry, status fuse.Status) {
return fs.FileSystem.OpenDir(fs.prefixed(name), context)
}
......@@ -80,31 +82,31 @@ func (fs *PrefixFileSystem) OnUnmount() {
fs.FileSystem.OnUnmount()
}
func (fs *PrefixFileSystem) Access(name string, mode uint32, context *Context) (code Status) {
func (fs *PrefixFileSystem) Access(name string, mode uint32, context *fuse.Context) (code fuse.Status) {
return fs.FileSystem.Access(fs.prefixed(name), mode, context)
}
func (fs *PrefixFileSystem) Create(name string, flags uint32, mode uint32, context *Context) (file File, code Status) {
func (fs *PrefixFileSystem) Create(name string, flags uint32, mode uint32, context *fuse.Context) (file fuse.File, code fuse.Status) {
return fs.FileSystem.Create(fs.prefixed(name), flags, mode, context)
}
func (fs *PrefixFileSystem) Utimens(name string, Atime *time.Time, Mtime *time.Time, context *Context) (code Status) {
func (fs *PrefixFileSystem) Utimens(name string, Atime *time.Time, Mtime *time.Time, context *fuse.Context) (code fuse.Status) {
return fs.FileSystem.Utimens(fs.prefixed(name), Atime, Mtime, context)
}
func (fs *PrefixFileSystem) GetXAttr(name string, attr string, context *Context) ([]byte, Status) {
func (fs *PrefixFileSystem) GetXAttr(name string, attr string, context *fuse.Context) ([]byte, fuse.Status) {
return fs.FileSystem.GetXAttr(fs.prefixed(name), attr, context)
}
func (fs *PrefixFileSystem) SetXAttr(name string, attr string, data []byte, flags int, context *Context) Status {
func (fs *PrefixFileSystem) SetXAttr(name string, attr string, data []byte, flags int, context *fuse.Context) fuse.Status {
return fs.FileSystem.SetXAttr(fs.prefixed(name), attr, data, flags, context)
}
func (fs *PrefixFileSystem) ListXAttr(name string, context *Context) ([]string, Status) {
func (fs *PrefixFileSystem) ListXAttr(name string, context *fuse.Context) ([]string, fuse.Status) {
return fs.FileSystem.ListXAttr(fs.prefixed(name), context)
}
func (fs *PrefixFileSystem) RemoveXAttr(name string, attr string, context *Context) Status {
func (fs *PrefixFileSystem) RemoveXAttr(name string, attr string, context *fuse.Context) fuse.Status {
return fs.FileSystem.RemoveXAttr(fs.prefixed(name), attr, context)
}
......
package fuse
package pathfs
import (
"fmt"
"time"
"github.com/hanwen/go-fuse/fuse"
)
// This is a wrapper that only exposes read-only operations.
......@@ -12,63 +14,63 @@ type ReadonlyFileSystem struct {
var _ = (FileSystem)((*ReadonlyFileSystem)(nil))
func (fs *ReadonlyFileSystem) GetAttr(name string, context *Context) (*Attr, Status) {
func (fs *ReadonlyFileSystem) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Status) {
return fs.FileSystem.GetAttr(name, context)
}
func (fs *ReadonlyFileSystem) Readlink(name string, context *Context) (string, Status) {
func (fs *ReadonlyFileSystem) Readlink(name string, context *fuse.Context) (string, fuse.Status) {
return fs.FileSystem.Readlink(name, context)
}
func (fs *ReadonlyFileSystem) Mknod(name string, mode uint32, dev uint32, context *Context) Status {
return EPERM
func (fs *ReadonlyFileSystem) Mknod(name string, mode uint32, dev uint32, context *fuse.Context) fuse.Status {
return fuse.EPERM
}
func (fs *ReadonlyFileSystem) Mkdir(name string, mode uint32, context *Context) Status {
return EPERM
func (fs *ReadonlyFileSystem) Mkdir(name string, mode uint32, context *fuse.Context) fuse.Status {
return fuse.EPERM
}
func (fs *ReadonlyFileSystem) Unlink(name string, context *Context) (code Status) {
return EPERM
func (fs *ReadonlyFileSystem) Unlink(name string, context *fuse.Context) (code fuse.Status) {
return fuse.EPERM
}
func (fs *ReadonlyFileSystem) Rmdir(name string, context *Context) (code Status) {
return EPERM
func (fs *ReadonlyFileSystem) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
return fuse.EPERM
}
func (fs *ReadonlyFileSystem) Symlink(value string, linkName string, context *Context) (code Status) {
return EPERM
func (fs *ReadonlyFileSystem) Symlink(value string, linkName string, context *fuse.Context) (code fuse.Status) {
return fuse.EPERM
}
func (fs *ReadonlyFileSystem) Rename(oldName string, newName string, context *Context) (code Status) {
return EPERM
func (fs *ReadonlyFileSystem) Rename(oldName string, newName string, context *fuse.Context) (code fuse.Status) {
return fuse.EPERM
}
func (fs *ReadonlyFileSystem) Link(oldName string, newName string, context *Context) (code Status) {
return EPERM
func (fs *ReadonlyFileSystem) Link(oldName string, newName string, context *fuse.Context) (code fuse.Status) {
return fuse.EPERM
}
func (fs *ReadonlyFileSystem) Chmod(name string, mode uint32, context *Context) (code Status) {
return EPERM
func (fs *ReadonlyFileSystem) Chmod(name string, mode uint32, context *fuse.Context) (code fuse.Status) {
return fuse.EPERM
}
func (fs *ReadonlyFileSystem) Chown(name string, uid uint32, gid uint32, context *Context) (code Status) {
return EPERM
func (fs *ReadonlyFileSystem) Chown(name string, uid uint32, gid uint32, context *fuse.Context) (code fuse.Status) {
return fuse.EPERM
}
func (fs *ReadonlyFileSystem) Truncate(name string, offset uint64, context *Context) (code Status) {
return EPERM
func (fs *ReadonlyFileSystem) Truncate(name string, offset uint64, context *fuse.Context) (code fuse.Status) {
return fuse.EPERM
}
func (fs *ReadonlyFileSystem) Open(name string, flags uint32, context *Context) (file File, code Status) {
if flags&O_ANYWRITE != 0 {
return nil, EPERM
func (fs *ReadonlyFileSystem) Open(name string, flags uint32, context *fuse.Context) (file fuse.File, code fuse.Status) {
if flags&fuse.O_ANYWRITE != 0 {
return nil, fuse.EPERM
}
file, code = fs.FileSystem.Open(name, flags, context)
return &ReadOnlyFile{file}, code
return &fuse.ReadOnlyFile{file}, code
}
func (fs *ReadonlyFileSystem) OpenDir(name string, context *Context) (stream []DirEntry, status Status) {
func (fs *ReadonlyFileSystem) OpenDir(name string, context *fuse.Context) (stream []fuse.DirEntry, status fuse.Status) {
return fs.FileSystem.OpenDir(name, context)
}
......@@ -84,30 +86,30 @@ func (fs *ReadonlyFileSystem) String() string {
return fmt.Sprintf("ReadonlyFileSystem(%v)", fs.FileSystem)
}
func (fs *ReadonlyFileSystem) Access(name string, mode uint32, context *Context) (code Status) {
func (fs *ReadonlyFileSystem) Access(name string, mode uint32, context *fuse.Context) (code fuse.Status) {
return fs.FileSystem.Access(name, mode, context)
}
func (fs *ReadonlyFileSystem) Create(name string, flags uint32, mode uint32, context *Context) (file File, code Status) {
return nil, EPERM
func (fs *ReadonlyFileSystem) Create(name string, flags uint32, mode uint32, context *fuse.Context) (file fuse.File, code fuse.Status) {
return nil, fuse.EPERM
}
func (fs *ReadonlyFileSystem) Utimens(name string, atime *time.Time, ctime *time.Time, context *Context) (code Status) {
return EPERM
func (fs *ReadonlyFileSystem) Utimens(name string, atime *time.Time, ctime *time.Time, context *fuse.Context) (code fuse.Status) {
return fuse.EPERM
}
func (fs *ReadonlyFileSystem) GetXAttr(name string, attr string, context *Context) ([]byte, Status) {
func (fs *ReadonlyFileSystem) GetXAttr(name string, attr string, context *fuse.Context) ([]byte, fuse.Status) {
return fs.FileSystem.GetXAttr(name, attr, context)
}
func (fs *ReadonlyFileSystem) SetXAttr(name string, attr string, data []byte, flags int, context *Context) Status {
return EPERM
func (fs *ReadonlyFileSystem) SetXAttr(name string, attr string, data []byte, flags int, context *fuse.Context) fuse.Status {
return fuse.EPERM
}
func (fs *ReadonlyFileSystem) ListXAttr(name string, context *Context) ([]string, Status) {
func (fs *ReadonlyFileSystem) ListXAttr(name string, context *fuse.Context) ([]string, fuse.Status) {
return fs.FileSystem.ListXAttr(name, context)
}
func (fs *ReadonlyFileSystem) RemoveXAttr(name string, attr string, context *Context) Status {
return EPERM
func (fs *ReadonlyFileSystem) RemoveXAttr(name string, attr string, context *fuse.Context) fuse.Status {
return fuse.EPERM
}
package pathfs
import (
"bytes"
"syscall"
"unsafe"
)
func getxattr(path string, attr string, dest []byte) (sz int, errno int) {
pathBs := syscall.StringBytePtr(path)
attrBs := syscall.StringBytePtr(attr)
size, _, errNo := syscall.Syscall6(
syscall.SYS_GETXATTR,
uintptr(unsafe.Pointer(pathBs)),
uintptr(unsafe.Pointer(attrBs)),
uintptr(unsafe.Pointer(&dest[0])),
uintptr(len(dest)),
0, 0)
return int(size), int(errNo)
}
func GetXAttr(path string, attr string, dest []byte) (value []byte, errno int) {
sz, errno := getxattr(path, attr, dest)
for sz > cap(dest) && errno == 0 {
dest = make([]byte, sz)
sz, errno = getxattr(path, attr, dest)
}
if errno != 0 {
return nil, errno
}
return dest[:sz], errno
}
func listxattr(path string, dest []byte) (sz int, errno int) {
pathbs := syscall.StringBytePtr(path)
var destPointer unsafe.Pointer
if len(dest) > 0 {
destPointer = unsafe.Pointer(&dest[0])
}
size, _, errNo := syscall.Syscall(
syscall.SYS_LISTXATTR,
uintptr(unsafe.Pointer(pathbs)),
uintptr(destPointer),
uintptr(len(dest)))
return int(size), int(errNo)
}
func ListXAttr(path string) (attributes []string, errno int) {
dest := make([]byte, 0)
sz, errno := listxattr(path, dest)
if errno != 0 {
return nil, errno
}
for sz > cap(dest) && errno == 0 {
dest = make([]byte, sz)
sz, errno = listxattr(path, dest)
}
// -1 to drop the final empty slice.
dest = dest[:sz-1]
attributesBytes := bytes.Split(dest, []byte{0})
attributes = make([]string, len(attributesBytes))
for i, v := range attributesBytes {
attributes[i] = string(v)
}
return attributes, errno
}
func Setxattr(path string, attr string, data []byte, flags int) (errno int) {
pathbs := syscall.StringBytePtr(path)
attrbs := syscall.StringBytePtr(attr)
_, _, errNo := syscall.Syscall6(
syscall.SYS_SETXATTR,
uintptr(unsafe.Pointer(pathbs)),
uintptr(unsafe.Pointer(attrbs)),
uintptr(unsafe.Pointer(&data[0])),
uintptr(len(data)),
uintptr(flags), 0)
return int(errNo)
}
func Removexattr(path string, attr string) (errno int) {
pathbs := syscall.StringBytePtr(path)
attrbs := syscall.StringBytePtr(attr)
_, _, errNo := syscall.Syscall(
syscall.SYS_REMOVEXATTR,
uintptr(unsafe.Pointer(pathbs)),
uintptr(unsafe.Pointer(attrbs)), 0)
return int(errNo)
}
package fuse
package pathfs
import (
"bytes"
......@@ -8,6 +8,8 @@ import (
"path/filepath"
"syscall"
"testing"
"github.com/hanwen/go-fuse/fuse"
)
var _ = log.Print
......@@ -35,64 +37,64 @@ func NewXAttrFs(nm string, m map[string][]byte) *XAttrTestFs {
return x
}
func (fs *XAttrTestFs) GetAttr(name string, context *Context) (*Attr, Status) {
a := &Attr{}
func (fs *XAttrTestFs) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Status) {
a := &fuse.Attr{}
if name == "" || name == "/" {
a.Mode = S_IFDIR | 0700
return a, OK
a.Mode = fuse.S_IFDIR | 0700
return a, fuse.OK
}
if name == fs.filename {
a.Mode = S_IFREG | 0600
return a, OK
a.Mode = fuse.S_IFREG | 0600
return a, fuse.OK
}
return nil, ENOENT
return nil, fuse.ENOENT
}
func (fs *XAttrTestFs) SetXAttr(name string, attr string, data []byte, flags int, context *Context) Status {
func (fs *XAttrTestFs) SetXAttr(name string, attr string, data []byte, flags int, context *fuse.Context) fuse.Status {
fs.tester.Log("SetXAttr", name, attr, string(data), flags)
if name != fs.filename {
return ENOENT
return fuse.ENOENT
}
dest := make([]byte, len(data))
copy(dest, data)
fs.attrs[attr] = dest
return OK
return fuse.OK
}
func (fs *XAttrTestFs) GetXAttr(name string, attr string, context *Context) ([]byte, Status) {
func (fs *XAttrTestFs) GetXAttr(name string, attr string, context *fuse.Context) ([]byte, fuse.Status) {
if name != fs.filename {
return nil, ENOENT
return nil, fuse.ENOENT
}
v, ok := fs.attrs[attr]
if !ok {
return nil, ENODATA
return nil, fuse.ENODATA
}
fs.tester.Log("GetXAttr", string(v))
return v, OK
return v, fuse.OK
}
func (fs *XAttrTestFs) ListXAttr(name string, context *Context) (data []string, code Status) {
func (fs *XAttrTestFs) ListXAttr(name string, context *fuse.Context) (data []string, code fuse.Status) {
if name != fs.filename {
return nil, ENOENT
return nil, fuse.ENOENT
}
for k := range fs.attrs {
data = append(data, k)
}
return data, OK
return data, fuse.OK
}
func (fs *XAttrTestFs) RemoveXAttr(name string, attr string, context *Context) Status {
func (fs *XAttrTestFs) RemoveXAttr(name string, attr string, context *fuse.Context) fuse.Status {
if name != fs.filename {
return ENOENT
return fuse.ENOENT
}
_, ok := fs.attrs[attr]
fs.tester.Log("RemoveXAttr", name, attr, ok)
if !ok {
return ENODATA
return fuse.ENODATA
}
delete(fs.attrs, attr)
return OK
return fuse.OK
}
func readXAttr(p, a string) (val []byte, errno int) {
......@@ -109,11 +111,11 @@ func xattrTestCase(t *testing.T, nm string) (mountPoint string, cleanup func())
}
nfs := NewPathNodeFs(xfs, nil)
state, _, err := MountNodeFileSystem(mountPoint, nfs, nil)
state, _, err := fuse.MountNodeFileSystem(mountPoint, nfs, nil)
if err != nil {
t.Fatalf("TempDir failed: %v", err)
}
state.Debug = VerboseTest()
state.Debug = fuse.VerboseTest()
go state.Loop()
return mountPoint, func() {
......@@ -180,7 +182,7 @@ func TestXAttrRead(t *testing.T) {
Removexattr(mounted, "third")
val, errno = readXAttr(mounted, "third")
if errno != int(ENODATA) {
if errno != int(fuse.ENODATA) {
t.Error("Data not removed?", errno, val)
}
}
package fuse
import (
"fmt"
"io/ioutil"
"log"
"os"
"regexp"
"sync"
"testing"
"time"
)
var _ = log.Println
// This test checks that highly concurrent loads don't use a lot of
// memory if it is not needed: The input buffer needs to accomodata
// the max write size, but it is only really needed when we are
// processing writes.
type DelayFs struct {
DefaultFileSystem
fileRegex *regexp.Regexp
dirRegex *regexp.Regexp
}
func (d *DelayFs) GetAttr(name string, c *Context) (*Attr, Status) {
if name == "" || d.dirRegex.MatchString(name) {
return &Attr{Mode: S_IFDIR | 0755}, OK
}
if d.fileRegex.MatchString(name) {
time.Sleep(time.Second)
return &Attr{Mode: S_IFREG | 0644}, OK
}
return nil, ENOENT
}
func TestMemoryPressure(t *testing.T) {
fs := &DelayFs{
fileRegex: regexp.MustCompile("^dir[0-9]*/file[0-9]*$"),
dirRegex: regexp.MustCompile("^dir[0-9]*$"),
}
dir, err := ioutil.TempDir("", "go-fuse-pressure_test")
if err != nil {
t.Fatalf("TempDir failed: %v", err)
}
defer os.RemoveAll(dir)
nfs := NewPathNodeFs(fs, nil)
o := &FileSystemOptions{PortableInodes: true}
conn := NewFileSystemConnector(nfs, o)
state := NewMountState(conn)
bufs := NewBufferPool()
err = state.Mount(dir, &MountOptions{Buffers: bufs})
if err != nil {
t.Fatalf("mount failed: %v", err)
}
state.Debug = VerboseTest()
go state.Loop()
defer state.Unmount()
// Wait for FS to get ready.
os.Lstat(dir)
var wg sync.WaitGroup
for i := 0; i < 10*_MAX_READERS; i++ {
wg.Add(1)
go func(x int) {
fn := fmt.Sprintf("%s/dir%d/file%d", dir, x, x)
_, err := os.Lstat(fn)
if err != nil {
t.Errorf("parallel stat %q: %v", fn, err)
}
wg.Done()
}(i)
}
time.Sleep(100 * time.Millisecond)
state.reqMu.Lock()
bufs.lock.Lock()
created := bufs.createdBuffers + state.outstandingReadBufs
bufs.lock.Unlock()
state.reqMu.Unlock()
t.Logf("Have %d read bufs", state.outstandingReadBufs)
// +1 due to batch forget?
if created > _MAX_READERS+1 {
t.Errorf("created %d buffers, max reader %d", created, _MAX_READERS)
}
wg.Wait()
}
......@@ -125,4 +125,3 @@ func Removexattr(path string, attr string) (errno int) {
uintptr(unsafe.Pointer(attrbs)), 0)
return int(errNo)
}
package fuse
import (
"bytes"
"os"
"syscall"
"unsafe"
......@@ -37,96 +36,6 @@ func Writev(fd int, packet [][]byte) (n int, err error) {
return n, err
}
func getxattr(path string, attr string, dest []byte) (sz int, errno int) {
pathBs := syscall.StringBytePtr(path)
attrBs := syscall.StringBytePtr(attr)
size, _, errNo := syscall.Syscall6(
syscall.SYS_GETXATTR,
uintptr(unsafe.Pointer(pathBs)),
uintptr(unsafe.Pointer(attrBs)),
uintptr(unsafe.Pointer(&dest[0])),
uintptr(len(dest)),
0, 0)
return int(size), int(errNo)
}
func GetXAttr(path string, attr string, dest []byte) (value []byte, errno int) {
sz, errno := getxattr(path, attr, dest)
for sz > cap(dest) && errno == 0 {
dest = make([]byte, sz)
sz, errno = getxattr(path, attr, dest)
}
if errno != 0 {
return nil, errno
}
return dest[:sz], errno
}
func listxattr(path string, dest []byte) (sz int, errno int) {
pathbs := syscall.StringBytePtr(path)
var destPointer unsafe.Pointer
if len(dest) > 0 {
destPointer = unsafe.Pointer(&dest[0])
}
size, _, errNo := syscall.Syscall(
syscall.SYS_LISTXATTR,
uintptr(unsafe.Pointer(pathbs)),
uintptr(destPointer),
uintptr(len(dest)))
return int(size), int(errNo)
}
func ListXAttr(path string) (attributes []string, errno int) {
dest := make([]byte, 0)
sz, errno := listxattr(path, dest)
if errno != 0 {
return nil, errno
}
for sz > cap(dest) && errno == 0 {
dest = make([]byte, sz)
sz, errno = listxattr(path, dest)
}
// -1 to drop the final empty slice.
dest = dest[:sz-1]
attributesBytes := bytes.Split(dest, []byte{0})
attributes = make([]string, len(attributesBytes))
for i, v := range attributesBytes {
attributes[i] = string(v)
}
return attributes, errno
}
func Setxattr(path string, attr string, data []byte, flags int) (errno int) {
pathbs := syscall.StringBytePtr(path)
attrbs := syscall.StringBytePtr(attr)
_, _, errNo := syscall.Syscall6(
syscall.SYS_SETXATTR,
uintptr(unsafe.Pointer(pathbs)),
uintptr(unsafe.Pointer(attrbs)),
uintptr(unsafe.Pointer(&data[0])),
uintptr(len(data)),
uintptr(flags), 0)
return int(errNo)
}
func Removexattr(path string, attr string) (errno int) {
pathbs := syscall.StringBytePtr(path)
attrbs := syscall.StringBytePtr(attr)
_, _, errNo := syscall.Syscall(
syscall.SYS_REMOVEXATTR,
uintptr(unsafe.Pointer(pathbs)),
uintptr(unsafe.Pointer(attrbs)), 0)
return int(errNo)
}
const AT_FDCWD = -100
func Linkat(fd1 int, n1 string, fd2 int, n2 string) int {
......
package fuse
package test
import (
"bytes"
"github.com/hanwen/go-fuse/raw"
"io/ioutil"
"log"
"os"
"sync"
"testing"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
"github.com/hanwen/go-fuse/raw"
)
var _ = log.Println
type cacheFs struct {
*LoopbackFileSystem
*pathfs.LoopbackFileSystem
}
func (fs *cacheFs) Open(name string, flags uint32, context *Context) (fuseFile File, status Status) {
func (fs *cacheFs) Open(name string, flags uint32, context *fuse.Context) (fuseFile fuse.File, status fuse.Status) {
f, c := fs.LoopbackFileSystem.Open(name, flags, context)
if !c.Ok() {
return f, c
}
return &WithFlags{
return &fuse.WithFlags{
File: f,
FuseFlags: raw.FOPEN_KEEP_CACHE,
}, c
}
func setupCacheTest(t *testing.T) (string, *PathNodeFs, func()) {
func setupCacheTest(t *testing.T) (string, *pathfs.PathNodeFs, func()) {
dir, err := ioutil.TempDir("", "go-fuse-cachetest")
if err != nil {
t.Fatalf("TempDir failed: %v", err)
......@@ -37,16 +40,16 @@ func setupCacheTest(t *testing.T) (string, *PathNodeFs, func()) {
os.Mkdir(dir+"/orig", 0755)
fs := &cacheFs{
LoopbackFileSystem: NewLoopbackFileSystem(dir + "/orig"),
LoopbackFileSystem: pathfs.NewLoopbackFileSystem(dir + "/orig"),
}
pfs := NewPathNodeFs(fs, nil)
state, conn, err := MountNodeFileSystem(dir+"/mnt", pfs, nil)
pfs := pathfs.NewPathNodeFs(fs, nil)
state, conn, err := fuse.MountNodeFileSystem(dir+"/mnt", pfs, nil)
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
}
state.Debug = VerboseTest()
conn.Debug = VerboseTest()
pfs.Debug = VerboseTest()
state.Debug = fuse.VerboseTest()
conn.Debug = fuse.VerboseTest()
pfs.Debug = fuse.VerboseTest()
go state.Loop()
return dir, pfs, func() {
......@@ -106,28 +109,28 @@ func TestCacheFs(t *testing.T) {
}
type nonseekFs struct {
DefaultFileSystem
pathfs.DefaultFileSystem
Length int
}
func (fs *nonseekFs) GetAttr(name string, context *Context) (fi *Attr, status Status) {
func (fs *nonseekFs) GetAttr(name string, context *fuse.Context) (fi *fuse.Attr, status fuse.Status) {
if name == "file" {
return &Attr{Mode: S_IFREG | 0644}, OK
return &fuse.Attr{Mode: fuse.S_IFREG | 0644}, fuse.OK
}
return nil, ENOENT
return nil, fuse.ENOENT
}
func (fs *nonseekFs) Open(name string, flags uint32, context *Context) (fuseFile File, status Status) {
func (fs *nonseekFs) Open(name string, flags uint32, context *fuse.Context) (fuseFile fuse.File, status fuse.Status) {
if name != "file" {
return nil, ENOENT
return nil, fuse.ENOENT
}
data := bytes.Repeat([]byte{42}, fs.Length)
f := NewDataFile(data)
return &WithFlags{
f := fuse.NewDataFile(data)
return &fuse.WithFlags{
File: f,
FuseFlags: raw.FOPEN_NONSEEKABLE,
}, OK
}, fuse.OK
}
func TestNonseekable(t *testing.T) {
......@@ -139,12 +142,12 @@ func TestNonseekable(t *testing.T) {
t.Fatalf("failed: %v", err)
}
defer os.RemoveAll(dir)
nfs := NewPathNodeFs(fs, nil)
state, _, err := MountNodeFileSystem(dir, nfs, nil)
nfs := pathfs.NewPathNodeFs(fs, nil)
state, _, err := fuse.MountNodeFileSystem(dir, nfs, nil)
if err != nil {
t.Fatalf("failed: %v", err)
}
state.Debug = VerboseTest()
state.Debug = fuse.VerboseTest()
defer state.Unmount()
go state.Loop()
......@@ -171,16 +174,16 @@ func TestGetAttrRace(t *testing.T) {
os.Mkdir(dir+"/mnt", 0755)
os.Mkdir(dir+"/orig", 0755)
fs := NewLoopbackFileSystem(dir + "/orig")
pfs := NewPathNodeFs(fs, nil)
state, conn, err := MountNodeFileSystem(dir+"/mnt", pfs,
&FileSystemOptions{})
fs := pathfs.NewLoopbackFileSystem(dir + "/orig")
pfs := pathfs.NewPathNodeFs(fs, nil)
state, conn, err := fuse.MountNodeFileSystem(dir+"/mnt", pfs,
&fuse.FileSystemOptions{})
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
}
state.Debug = VerboseTest()
conn.Debug = VerboseTest()
pfs.Debug = VerboseTest()
state.Debug = fuse.VerboseTest()
conn.Debug = fuse.VerboseTest()
pfs.Debug = fuse.VerboseTest()
go state.Loop()
defer state.Unmount()
......
......@@ -7,12 +7,13 @@ import (
"testing"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
)
var _ = log.Println
type DefaultReadFS struct {
fuse.DefaultFileSystem
pathfs.DefaultFileSystem
size uint64
exist bool
}
......@@ -38,7 +39,7 @@ func defaultReadTest(t *testing.T) (root string, cleanup func()) {
if err != nil {
t.Fatalf("TempDir failed: %v", err)
}
pathfs := fuse.NewPathNodeFs(fs, nil)
pathfs := pathfs.NewPathNodeFs(fs, nil)
state, _, err := fuse.MountNodeFileSystem(dir, pathfs, nil)
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
......
......@@ -59,7 +59,7 @@ func TestDeleteNotify(t *testing.T) {
ch.FsNode().SetInode(nil)
flip := flipNode{
FsNode: ch.FsNode(),
ok: make(chan int),
ok: make(chan int),
}
newCh := fs.Root().Inode().New(true, &flip)
fs.Root().Inode().AddChild("testdir", newCh)
......
......@@ -7,8 +7,9 @@ import (
"testing"
"time"
"github.com/hanwen/go-fuse/raw"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
"github.com/hanwen/go-fuse/raw"
)
type MutableDataFile struct {
......@@ -89,7 +90,7 @@ func (f *MutableDataFile) Chmod(perms uint32) fuse.Status {
// This FS only supports a single r/w file called "/file".
type FSetAttrFs struct {
fuse.DefaultFileSystem
pathfs.DefaultFileSystem
file *MutableDataFile
}
......@@ -131,12 +132,12 @@ func NewFile() *MutableDataFile {
return &MutableDataFile{}
}
func setupFAttrTest(t *testing.T, fs fuse.FileSystem) (dir string, clean func(), sync func()) {
func setupFAttrTest(t *testing.T, fs pathfs.FileSystem) (dir string, clean func(), sync func()) {
dir, err := ioutil.TempDir("", "go-fuse-fsetattr_test")
if err != nil {
t.Fatalf("TempDir failed: %v", err)
}
nfs := fuse.NewPathNodeFs(fs, nil)
nfs := pathfs.NewPathNodeFs(fs, nil)
state, _, err := fuse.MountNodeFileSystem(dir, nfs, nil)
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
......
......@@ -6,7 +6,6 @@ import (
"syscall"
"testing"
"time"
)
func TestTouch(t *testing.T) {
......
......@@ -14,8 +14,9 @@ import (
"syscall"
"testing"
"time"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
)
var _ = strings.Join
......@@ -37,7 +38,7 @@ type testCase struct {
origSubdir string
tester *testing.T
state *fuse.MountState
pathFs *fuse.PathNodeFs
pathFs *pathfs.PathNodeFs
connector *fuse.FileSystemConnector
}
......@@ -70,12 +71,12 @@ func NewTestCase(t *testing.T) *testCase {
me.origFile = filepath.Join(me.orig, name)
me.origSubdir = filepath.Join(me.orig, subdir)
var pfs fuse.FileSystem
pfs = fuse.NewLoopbackFileSystem(me.orig)
pfs = fuse.NewLockingFileSystem(pfs)
var pfs pathfs.FileSystem
pfs = pathfs.NewLoopbackFileSystem(me.orig)
pfs = pathfs.NewLockingFileSystem(pfs)
var rfs fuse.RawFileSystem
me.pathFs = fuse.NewPathNodeFs(pfs, &fuse.PathNodeFsOptions{
me.pathFs = pathfs.NewPathNodeFs(pfs, &pathfs.PathNodeFsOptions{
ClientInodes: true})
me.connector = fuse.NewFileSystemConnector(me.pathFs,
&fuse.FileSystemOptions{
......@@ -928,8 +929,8 @@ func TestOriginalIsSymlink(t *testing.T) {
t.Fatalf("Symlink failed: %v", err)
}
fs := fuse.NewLoopbackFileSystem(link)
nfs := fuse.NewPathNodeFs(fs, nil)
fs := pathfs.NewLoopbackFileSystem(link)
nfs := pathfs.NewPathNodeFs(fs, nil)
state, _, err := fuse.MountNodeFileSystem(mnt, nfs, nil)
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
......
......@@ -8,6 +8,7 @@ import (
"time"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
)
func TestMountOnExisting(t *testing.T) {
......@@ -43,7 +44,7 @@ func TestMountRename(t *testing.T) {
ts := NewTestCase(t)
defer ts.Cleanup()
fs := fuse.NewPathNodeFs(fuse.NewLoopbackFileSystem(ts.orig), nil)
fs := pathfs.NewPathNodeFs(pathfs.NewLoopbackFileSystem(ts.orig), nil)
code := ts.connector.Mount(ts.rootNode(), "mnt", fs, nil)
if !code.Ok() {
t.Fatal("mount should succeed")
......@@ -59,7 +60,7 @@ func TestMountReaddir(t *testing.T) {
ts := NewTestCase(t)
defer ts.Cleanup()
fs := fuse.NewPathNodeFs(fuse.NewLoopbackFileSystem(ts.orig), nil)
fs := pathfs.NewPathNodeFs(pathfs.NewLoopbackFileSystem(ts.orig), nil)
code := ts.connector.Mount(ts.rootNode(), "mnt", fs, nil)
if !code.Ok() {
t.Fatal("mount should succeed")
......@@ -84,7 +85,7 @@ func TestRecursiveMount(t *testing.T) {
t.Fatalf("WriteFile failed: %v", err)
}
fs := fuse.NewPathNodeFs(fuse.NewLoopbackFileSystem(ts.orig), nil)
fs := pathfs.NewPathNodeFs(pathfs.NewLoopbackFileSystem(ts.orig), nil)
code := ts.connector.Mount(ts.rootNode(), "mnt", fs, nil)
if !code.Ok() {
t.Fatal("mount should succeed")
......@@ -126,7 +127,7 @@ func TestDeletedUnmount(t *testing.T) {
defer ts.Cleanup()
submnt := filepath.Join(ts.mnt, "mnt")
pfs2 := fuse.NewPathNodeFs(fuse.NewLoopbackFileSystem(ts.orig), nil)
pfs2 := pathfs.NewPathNodeFs(pathfs.NewLoopbackFileSystem(ts.orig), nil)
code := ts.connector.Mount(ts.rootNode(), "mnt", pfs2, nil)
if !code.Ok() {
t.Fatal("Mount error", code)
......
......@@ -8,12 +8,13 @@ import (
"time"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
)
var _ = log.Println
type NotifyFs struct {
fuse.DefaultFileSystem
pathfs.DefaultFileSystem
size uint64
exist bool
}
......@@ -37,7 +38,7 @@ func (fs *NotifyFs) Open(name string, f uint32, context *fuse.Context) (fuse.Fil
type NotifyTest struct {
fs *NotifyFs
pathfs *fuse.PathNodeFs
pathfs *pathfs.PathNodeFs
connector *fuse.FileSystemConnector
dir string
state *fuse.MountState
......@@ -58,7 +59,7 @@ func NewNotifyTest(t *testing.T) *NotifyTest {
NegativeTimeout: entryTtl,
}
me.pathfs = fuse.NewPathNodeFs(me.fs, nil)
me.pathfs = pathfs.NewPathNodeFs(me.fs, nil)
me.state, me.connector, err = fuse.MountNodeFileSystem(me.dir, me.pathfs, opts)
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
......
......@@ -12,11 +12,12 @@ import (
"time"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
)
type knownFs struct {
*UnionFs
*fuse.PathNodeFs
*pathfs.PathNodeFs
}
// Creates unions for all files under a given directory,
......@@ -25,14 +26,14 @@ type knownFs struct {
//
// A union for A/B/C will placed under directory A-B-C.
type AutoUnionFs struct {
fuse.DefaultFileSystem
pathfs.DefaultFileSystem
lock sync.RWMutex
knownFileSystems map[string]knownFs
nameRootMap map[string]string
root string
nodeFs *fuse.PathNodeFs
nodeFs *pathfs.PathNodeFs
options *AutoUnionFsOptions
mountState *fuse.MountState
......@@ -42,7 +43,7 @@ type AutoUnionFs struct {
type AutoUnionFsOptions struct {
UnionFsOptions
fuse.FileSystemOptions
fuse.PathNodeFsOptions
pathfs.PathNodeFsOptions
// If set, run updateKnownFses() after mounting.
UpdateOnMount bool
......@@ -82,7 +83,7 @@ func (fs *AutoUnionFs) String() string {
return fmt.Sprintf("AutoUnionFs(%s)", fs.root)
}
func (fs *AutoUnionFs) OnMount(nodeFs *fuse.PathNodeFs) {
func (fs *AutoUnionFs) OnMount(nodeFs *pathfs.PathNodeFs) {
fs.nodeFs = nodeFs
if fs.options.UpdateOnMount {
time.AfterFunc(100*time.Millisecond, func() { fs.updateKnownFses() })
......@@ -123,7 +124,7 @@ func (fs *AutoUnionFs) createFs(name string, roots []string) fuse.Status {
}
log.Printf("Adding workspace %v for roots %v", name, ufs.String())
nfs := fuse.NewPathNodeFs(ufs, &fs.options.PathNodeFsOptions)
nfs := pathfs.NewPathNodeFs(ufs, &fs.options.PathNodeFsOptions)
code := fs.nodeFs.Mount(name, nfs, &fs.options.FileSystemOptions)
if code.Ok() {
fs.knownFileSystems[name] = knownFs{
......
......@@ -2,12 +2,14 @@ package unionfs
import (
"fmt"
"github.com/hanwen/go-fuse/fuse"
"io/ioutil"
"log"
"os"
"testing"
"time"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
)
var _ = fmt.Print
......@@ -53,7 +55,7 @@ func setup(t *testing.T) (workdir string, cleanup func()) {
fs := NewAutoUnionFs(wd+"/store", testAOpts)
nfs := fuse.NewPathNodeFs(fs, nil)
nfs := pathfs.NewPathNodeFs(fs, nil)
state, conn, err := fuse.MountNodeFileSystem(wd+"/mnt", nfs, &testAOpts.FileSystemOptions)
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
......
......@@ -2,10 +2,12 @@ package unionfs
import (
"fmt"
"github.com/hanwen/go-fuse/fuse"
"log"
"strings"
"time"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
)
var _ = fmt.Println
......@@ -34,7 +36,7 @@ type linkResponse struct {
// Caches filesystem metadata.
type CachingFileSystem struct {
fuse.FileSystem
pathfs.FileSystem
attributes *TimedCache
dirs *TimedCache
......@@ -42,7 +44,7 @@ type CachingFileSystem struct {
xattr *TimedCache
}
func readDir(fs fuse.FileSystem, name string) *dirResponse {
func readDir(fs pathfs.FileSystem, name string) *dirResponse {
origStream, code := fs.OpenDir(name, nil)
r := &dirResponse{nil, code}
......@@ -53,7 +55,7 @@ func readDir(fs fuse.FileSystem, name string) *dirResponse {
return r
}
func getAttr(fs fuse.FileSystem, name string) *attrResponse {
func getAttr(fs pathfs.FileSystem, name string) *attrResponse {
a, code := fs.GetAttr(name, nil)
return &attrResponse{
Attr: a,
......@@ -61,7 +63,7 @@ func getAttr(fs fuse.FileSystem, name string) *attrResponse {
}
}
func getXAttr(fs fuse.FileSystem, nameAttr string) *xattrResponse {
func getXAttr(fs pathfs.FileSystem, nameAttr string) *xattrResponse {
ns := strings.SplitN(nameAttr, _XATTRSEP, 2)
a, code := fs.GetXAttr(ns[0], ns[1], nil)
return &xattrResponse{
......@@ -70,7 +72,7 @@ func getXAttr(fs fuse.FileSystem, nameAttr string) *xattrResponse {
}
}
func readLink(fs fuse.FileSystem, name string) *linkResponse {
func readLink(fs pathfs.FileSystem, name string) *linkResponse {
a, code := fs.Readlink(name, nil)
return &linkResponse{
linkContent: a,
......@@ -78,7 +80,7 @@ func readLink(fs fuse.FileSystem, name string) *linkResponse {
}
}
func NewCachingFileSystem(fs fuse.FileSystem, ttl time.Duration) *CachingFileSystem {
func NewCachingFileSystem(fs pathfs.FileSystem, ttl time.Duration) *CachingFileSystem {
c := new(CachingFileSystem)
c.FileSystem = fs
c.attributes = NewTimedCache(func(n string) (interface{}, bool) {
......
......@@ -2,12 +2,14 @@ package unionfs
import (
"fmt"
"github.com/hanwen/go-fuse/fuse"
"io/ioutil"
"log"
"os"
"syscall"
"testing"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
)
var _ = fmt.Print
......@@ -31,7 +33,7 @@ func TestCachingFs(t *testing.T) {
wd, _ := ioutil.TempDir("", "")
defer os.RemoveAll(wd)
fs := fuse.NewLoopbackFileSystem(wd)
fs := pathfs.NewLoopbackFileSystem(wd)
cfs := NewCachingFileSystem(fs, 0)
os.Mkdir(wd+"/orig", 0755)
......
package unionfs
import (
"github.com/hanwen/go-fuse/fuse"
"os"
"github.com/hanwen/go-fuse/fuse/pathfs"
)
func NewUnionFsFromRoots(roots []string, opts *UnionFsOptions, roCaching bool) (*UnionFs, error) {
fses := make([]fuse.FileSystem, 0)
fses := make([]pathfs.FileSystem, 0)
for i, r := range roots {
var fs fuse.FileSystem
var fs pathfs.FileSystem
fi, err := os.Stat(r)
if err != nil {
return nil, err
}
if fi.IsDir() {
fs = fuse.NewLoopbackFileSystem(r)
fs = pathfs.NewLoopbackFileSystem(r)
}
if fs == nil {
return nil, err
......
package unionfs
import (
"github.com/hanwen/go-fuse/fuse"
"log"
"sync"
"time"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
)
// newDirnameMap reads the contents of the given directory. On error,
// returns a nil map. This forces reloads in the DirCache until we
// succeed.
func newDirnameMap(fs fuse.FileSystem, dir string) map[string]bool {
func newDirnameMap(fs pathfs.FileSystem, dir string) map[string]bool {
stream, code := fs.OpenDir(dir, nil)
if code == fuse.ENOENT {
// The directory not existing is not an error.
......@@ -38,7 +40,7 @@ func newDirnameMap(fs fuse.FileSystem, dir string) map[string]bool {
type DirCache struct {
dir string
ttl time.Duration
fs fuse.FileSystem
fs pathfs.FileSystem
// Protects data below.
lock sync.RWMutex
......@@ -100,7 +102,7 @@ func (c *DirCache) AddEntry(name string) {
c.names[name] = true
}
func NewDirCache(fs fuse.FileSystem, dir string, ttl time.Duration) *DirCache {
func NewDirCache(fs pathfs.FileSystem, dir string, ttl time.Duration) *DirCache {
dc := new(DirCache)
dc.dir = dir
dc.fs = fs
......
......@@ -3,8 +3,6 @@ package unionfs
import (
"crypto/md5"
"fmt"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/raw"
"log"
"os"
"path"
......@@ -13,6 +11,10 @@ import (
"sync"
"syscall"
"time"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
"github.com/hanwen/go-fuse/raw"
)
func filePathHash(path string) string {
......@@ -55,10 +57,10 @@ func filePathHash(path string) string {
*/
type UnionFs struct {
fuse.DefaultFileSystem
pathfs.DefaultFileSystem
// The same, but as interfaces.
fileSystems []fuse.FileSystem
fileSystems []pathfs.FileSystem
// A file-existence cache.
deletionCache *DirCache
......@@ -70,7 +72,7 @@ type UnionFs struct {
hiddenFiles map[string]bool
options *UnionFsOptions
nodeFs *fuse.PathNodeFs
nodeFs *pathfs.PathNodeFs
}
type UnionFsOptions struct {
......@@ -84,7 +86,7 @@ const (
_DROP_CACHE = ".drop_cache"
)
func NewUnionFs(fileSystems []fuse.FileSystem, options UnionFsOptions) *UnionFs {
func NewUnionFs(fileSystems []pathfs.FileSystem, options UnionFsOptions) *UnionFs {
g := new(UnionFs)
g.options = &options
g.fileSystems = fileSystems
......@@ -109,7 +111,7 @@ func NewUnionFs(fileSystems []fuse.FileSystem, options UnionFsOptions) *UnionFs
return g
}
func (fs *UnionFs) OnMount(nodeFs *fuse.PathNodeFs) {
func (fs *UnionFs) OnMount(nodeFs *pathfs.PathNodeFs) {
fs.nodeFs = nodeFs
}
......@@ -275,7 +277,7 @@ func (fs *UnionFs) Promote(name string, srcResult branchResult, context *fuse.Co
fs.promoteDirsTo(name)
if srcResult.attr.IsRegular() {
code = fuse.CopyFile(sourceFs, writable, name, name, context)
code = pathfs.CopyFile(sourceFs, writable, name, name, context)
if code.Ok() {
code = writable.Chmod(name, srcResult.attr.Mode&07777|0200, context)
......@@ -598,7 +600,7 @@ func (fs *UnionFs) Readlink(name string, context *fuse.Context) (out string, cod
return "", fuse.ENOENT
}
func IsDir(fs fuse.FileSystem, name string) bool {
func IsDir(fs pathfs.FileSystem, name string) bool {
a, code := fs.GetAttr(name, nil)
return code.Ok() && a.IsDir()
}
......@@ -742,7 +744,7 @@ func (fs *UnionFs) OpenDir(directory string, context *fuse.Context) (stream []fu
for i, l := range fs.fileSystems {
if i >= dirBranch.branch {
wg.Add(1)
go func(j int, pfs fuse.FileSystem) {
go func(j int, pfs pathfs.FileSystem) {
ch, s := pfs.OpenDir(directory, context)
statuses[j] = s
for _, v := range ch {
......
......@@ -16,6 +16,7 @@ import (
"time"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
"github.com/hanwen/go-fuse/raw"
)
......@@ -76,10 +77,10 @@ func setupUfs(t *testing.T) (workdir string, cleanup func()) {
t.Fatalf("Mkdir failed: %v", err)
}
var fses []fuse.FileSystem
fses = append(fses, fuse.NewLoopbackFileSystem(wd+"/rw"))
var fses []pathfs.FileSystem
fses = append(fses, pathfs.NewLoopbackFileSystem(wd+"/rw"))
fses = append(fses,
NewCachingFileSystem(fuse.NewLoopbackFileSystem(wd+"/ro"), 0))
NewCachingFileSystem(pathfs.NewLoopbackFileSystem(wd+"/ro"), 0))
ufs := NewUnionFs(fses, testOpts)
// We configure timeouts are smaller, so we can check for
......@@ -90,8 +91,8 @@ func setupUfs(t *testing.T) (workdir string, cleanup func()) {
NegativeTimeout: entryTtl / 2,
}
pathfs := fuse.NewPathNodeFs(ufs,
&fuse.PathNodeFsOptions{ClientInodes: true})
pathfs := pathfs.NewPathNodeFs(ufs,
&pathfs.PathNodeFsOptions{ClientInodes: true})
state, conn, err := fuse.MountNodeFileSystem(wd+"/mnt", pathfs, opts)
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
......@@ -1099,10 +1100,10 @@ func TestUnionFsDisappearing(t *testing.T) {
t.Fatalf("Mkdir failed: %v", err)
}
wrFs := fuse.NewLoopbackFileSystem(wd + "/rw")
var fses []fuse.FileSystem
wrFs := pathfs.NewLoopbackFileSystem(wd + "/rw")
var fses []pathfs.FileSystem
fses = append(fses, wrFs)
fses = append(fses, fuse.NewLoopbackFileSystem(wd+"/ro"))
fses = append(fses, pathfs.NewLoopbackFileSystem(wd+"/ro"))
ufs := NewUnionFs(fses, testOpts)
opts := &fuse.FileSystemOptions{
......@@ -1111,7 +1112,7 @@ func TestUnionFsDisappearing(t *testing.T) {
NegativeTimeout: entryTtl,
}
nfs := fuse.NewPathNodeFs(ufs, nil)
nfs := pathfs.NewPathNodeFs(ufs, nil)
state, _, err := fuse.MountNodeFileSystem(wd+"/mnt", nfs, opts)
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
......
......@@ -11,14 +11,16 @@ symlinking path/to/zipfile to /config/zipmount
*/
import (
"github.com/hanwen/go-fuse/fuse"
"log"
"path/filepath"
"sync"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
)
var _ = log.Printf
var _ = (fuse.FileSystem)((*MultiZipFs)(nil))
var _ = (pathfs.FileSystem)((*MultiZipFs)(nil))
const (
CONFIG_PREFIX = "config/"
......@@ -32,8 +34,8 @@ type MultiZipFs struct {
zips map[string]*MemTreeFs
dirZipFileMap map[string]string
nodeFs *fuse.PathNodeFs
fuse.DefaultFileSystem
nodeFs *pathfs.PathNodeFs
pathfs.DefaultFileSystem
}
func NewMultiZipFs() *MultiZipFs {
......@@ -47,7 +49,7 @@ func (fs *MultiZipFs) String() string {
return "MultiZipFs"
}
func (fs *MultiZipFs) OnMount(nodeFs *fuse.PathNodeFs) {
func (fs *MultiZipFs) OnMount(nodeFs *pathfs.PathNodeFs) {
fs.nodeFs = nodeFs
}
......
package zipfs
import (
"github.com/hanwen/go-fuse/fuse"
"io/ioutil"
"log"
"os"
"testing"
"time"
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/pathfs"
)
var _ = log.Printf
......@@ -16,7 +18,7 @@ const testTtl = 100 * time.Millisecond
func setupMzfs(t *testing.T) (mountPoint string, cleanup func()) {
fs := NewMultiZipFs()
mountPoint, _ = ioutil.TempDir("", "")
nfs := fuse.NewPathNodeFs(fs, nil)
nfs := pathfs.NewPathNodeFs(fs, nil)
state, _, err := fuse.MountNodeFileSystem(mountPoint, nfs, &fuse.FileSystemOptions{
EntryTimeout: testTtl,
AttrTimeout: testTtl,
......
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