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

nodefs: use syscall.Errno instead of fuse.Status

parent f1ff19a7
This diff is collapsed.
This diff is collapsed.
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"sync" "sync"
"syscall"
"testing" "testing"
"github.com/hanwen/go-fuse/fuse" "github.com/hanwen/go-fuse/fuse"
...@@ -33,31 +34,31 @@ func (f *keepCacheFile) setContent(delta int) { ...@@ -33,31 +34,31 @@ func (f *keepCacheFile) setContent(delta int) {
f.content = []byte(fmt.Sprintf("%010x", f.count)) f.content = []byte(fmt.Sprintf("%010x", f.count))
} }
func (f *keepCacheFile) Open(ctx context.Context, flags uint32) (FileHandle, uint32, fuse.Status) { func (f *keepCacheFile) Open(ctx context.Context, flags uint32) (FileHandle, uint32, syscall.Errno) {
var fl uint32 var fl uint32
if f.keepCache { if f.keepCache {
fl = fuse.FOPEN_KEEP_CACHE fl = fuse.FOPEN_KEEP_CACHE
} }
f.setContent(0) f.setContent(0)
return nil, fl, fuse.OK return nil, fl, OK
} }
func (f *keepCacheFile) GetAttr(ctx context.Context, out *fuse.AttrOut) fuse.Status { func (f *keepCacheFile) GetAttr(ctx context.Context, out *fuse.AttrOut) syscall.Errno {
f.mu.Lock() f.mu.Lock()
defer f.mu.Unlock() defer f.mu.Unlock()
out.Size = uint64(len(f.content)) out.Size = uint64(len(f.content))
return fuse.OK return OK
} }
func (f *keepCacheFile) Read(ctx context.Context, fh FileHandle, dest []byte, off int64) (fuse.ReadResult, fuse.Status) { func (f *keepCacheFile) Read(ctx context.Context, fh FileHandle, dest []byte, off int64) (fuse.ReadResult, syscall.Errno) {
f.setContent(1) f.setContent(1)
f.mu.Lock() f.mu.Lock()
defer f.mu.Unlock() defer f.mu.Unlock()
return fuse.ReadResultData(f.content[off:]), fuse.OK return fuse.ReadResultData(f.content[off:]), OK
} }
type keepCacheRoot struct { type keepCacheRoot struct {
...@@ -112,7 +113,7 @@ func TestKeepCache(t *testing.T) { ...@@ -112,7 +113,7 @@ func TestKeepCache(t *testing.T) {
t.Errorf("keep read 2 got %q want read 1 %q", c2, c1) t.Errorf("keep read 2 got %q want read 1 %q", c2, c1)
} }
if s := InodeOf(root.keep).NotifyContent(0, 100); !s.Ok() { if s := InodeOf(root.keep).NotifyContent(0, 100); s != OK {
t.Errorf("NotifyContent: %v", s) t.Errorf("NotifyContent: %v", s)
} }
......
// Copyright 2019 the Go-FUSE Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package nodefs
import (
"syscall"
"github.com/hanwen/go-fuse/fuse"
)
// OK is the Errno return value to indicate absense of errors.
var OK = syscall.Errno(0)
func ToErrno(err error) syscall.Errno {
s := fuse.ToStatus(err)
return syscall.Errno(s)
}
// Copyright 2019 the Go-FUSE Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package nodefs
import "syscall"
// ENOATTR indicates that an extended attribute was not present.
var ENOATTR = syscall.ENOATTR
// Copyright 2019 the Go-FUSE Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package nodefs
import "syscall"
// ENOATTR indicates that an extended attribute was not present.
var ENOATTR = syscall.ENODATA
This diff is collapsed.
...@@ -30,14 +30,14 @@ type dioFH struct { ...@@ -30,14 +30,14 @@ type dioFH struct {
DefaultFileHandle DefaultFileHandle
} }
func (f *dioFH) Lseek(ctx context.Context, off uint64, whence uint32) (uint64, fuse.Status) { func (f *dioFH) Lseek(ctx context.Context, off uint64, whence uint32) (uint64, syscall.Errno) {
next := (off + 1023) & (^uint64(1023)) next := (off + 1023) & (^uint64(1023))
return next, fuse.OK return next, OK
} }
func (fh *dioFH) Read(ctx context.Context, data []byte, off int64) (fuse.ReadResult, fuse.Status) { func (fh *dioFH) Read(ctx context.Context, data []byte, off int64) (fuse.ReadResult, syscall.Errno) {
r := bytes.Repeat([]byte(fmt.Sprintf("%010d", off)), 1+len(data)/10) r := bytes.Repeat([]byte(fmt.Sprintf("%010d", off)), 1+len(data)/10)
return fuse.ReadResultData(r[:len(data)]), fuse.OK return fuse.ReadResultData(r[:len(data)]), OK
} }
// overrides Open so it can return a dioFH file handle // overrides Open so it can return a dioFH file handle
...@@ -45,8 +45,8 @@ type dioFile struct { ...@@ -45,8 +45,8 @@ type dioFile struct {
DefaultOperations DefaultOperations
} }
func (f *dioFile) Open(ctx context.Context, flags uint32) (fh FileHandle, fuseFlags uint32, status fuse.Status) { func (f *dioFile) Open(ctx context.Context, flags uint32) (fh FileHandle, fuseFlags uint32, errno syscall.Errno) {
return &dioFH{}, fuse.FOPEN_DIRECT_IO, fuse.OK return &dioFH{}, fuse.FOPEN_DIRECT_IO, OK
} }
func TestDirectIO(t *testing.T) { func TestDirectIO(t *testing.T) {
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
package nodefs package nodefs
import ( import (
"syscall"
"github.com/hanwen/go-fuse/fuse" "github.com/hanwen/go-fuse/fuse"
) )
...@@ -16,10 +18,10 @@ func (a *dirArray) HasNext() bool { ...@@ -16,10 +18,10 @@ func (a *dirArray) HasNext() bool {
return len(a.entries) > 0 return len(a.entries) > 0
} }
func (a *dirArray) Next() (fuse.DirEntry, fuse.Status) { func (a *dirArray) Next() (fuse.DirEntry, syscall.Errno) {
e := a.entries[0] e := a.entries[0]
a.entries = a.entries[1:] a.entries = a.entries[1:]
return e, fuse.OK return e, 0
} }
func (a *dirArray) Close() { func (a *dirArray) Close() {
......
...@@ -7,14 +7,15 @@ package nodefs ...@@ -7,14 +7,15 @@ package nodefs
import ( import (
"io" "io"
"os" "os"
"syscall"
"github.com/hanwen/go-fuse/fuse" "github.com/hanwen/go-fuse/fuse"
) )
func NewLoopbackDirStream(nm string) (DirStream, fuse.Status) { func NewLoopbackDirStream(nm string) (DirStream, syscall.Errno) {
f, err := os.Open(nm) f, err := os.Open(nm)
if err != nil { if err != nil {
return nil, fuse.ToStatus(err) return nil, ToErrno(err)
} }
defer f.Close() defer f.Close()
...@@ -39,9 +40,9 @@ func NewLoopbackDirStream(nm string) (DirStream, fuse.Status) { ...@@ -39,9 +40,9 @@ func NewLoopbackDirStream(nm string) (DirStream, fuse.Status) {
} }
if err != nil { if err != nil {
return nil, fuse.ToStatus(err) return nil, ToErrno(err)
} }
} }
return &dirArray{entries}, fuse.OK return &dirArray{entries}, OK
} }
...@@ -18,10 +18,10 @@ type loopbackDirStream struct { ...@@ -18,10 +18,10 @@ type loopbackDirStream struct {
} }
// NewLoopbackDirStream open a directory for reading as a DirStream // NewLoopbackDirStream open a directory for reading as a DirStream
func NewLoopbackDirStream(name string) (DirStream, fuse.Status) { func NewLoopbackDirStream(name string) (DirStream, syscall.Errno) {
fd, err := syscall.Open(name, syscall.O_DIRECTORY, 0755) fd, err := syscall.Open(name, syscall.O_DIRECTORY, 0755)
if err != nil { if err != nil {
return nil, fuse.ToStatus(err) return nil, ToErrno(err)
} }
ds := &loopbackDirStream{ ds := &loopbackDirStream{
...@@ -29,11 +29,11 @@ func NewLoopbackDirStream(name string) (DirStream, fuse.Status) { ...@@ -29,11 +29,11 @@ func NewLoopbackDirStream(name string) (DirStream, fuse.Status) {
fd: fd, fd: fd,
} }
if err := ds.load(); !err.Ok() { if err := ds.load(); err != 0 {
ds.Close() ds.Close()
return nil, err return nil, err
} }
return ds, fuse.OK return ds, OK
} }
func (ds *loopbackDirStream) Close() { func (ds *loopbackDirStream) Close() {
...@@ -44,7 +44,7 @@ func (ds *loopbackDirStream) HasNext() bool { ...@@ -44,7 +44,7 @@ func (ds *loopbackDirStream) HasNext() bool {
return len(ds.todo) > 0 return len(ds.todo) > 0
} }
func (ds *loopbackDirStream) Next() (fuse.DirEntry, fuse.Status) { func (ds *loopbackDirStream) Next() (fuse.DirEntry, syscall.Errno) {
de := (*syscall.Dirent)(unsafe.Pointer(&ds.todo[0])) de := (*syscall.Dirent)(unsafe.Pointer(&ds.todo[0]))
nameBytes := ds.todo[unsafe.Offsetof(syscall.Dirent{}.Name):de.Reclen] nameBytes := ds.todo[unsafe.Offsetof(syscall.Dirent{}.Name):de.Reclen]
...@@ -64,15 +64,15 @@ func (ds *loopbackDirStream) Next() (fuse.DirEntry, fuse.Status) { ...@@ -64,15 +64,15 @@ func (ds *loopbackDirStream) Next() (fuse.DirEntry, fuse.Status) {
return result, ds.load() return result, ds.load()
} }
func (ds *loopbackDirStream) load() fuse.Status { func (ds *loopbackDirStream) load() syscall.Errno {
if len(ds.todo) > 0 { if len(ds.todo) > 0 {
return fuse.OK return OK
} }
n, err := syscall.Getdents(ds.fd, ds.buf) n, err := syscall.Getdents(ds.fd, ds.buf)
if err != nil { if err != nil {
return fuse.ToStatus(err) return ToErrno(err)
} }
ds.todo = ds.buf[:n] ds.todo = ds.buf[:n]
return fuse.OK return OK
} }
...@@ -24,36 +24,36 @@ type loopbackFile struct { ...@@ -24,36 +24,36 @@ type loopbackFile struct {
fd int fd int
} }
func (f *loopbackFile) Read(ctx context.Context, buf []byte, off int64) (res fuse.ReadResult, status fuse.Status) { func (f *loopbackFile) Read(ctx context.Context, buf []byte, off int64) (res fuse.ReadResult, errno syscall.Errno) {
r := fuse.ReadResultFd(uintptr(f.fd), off, len(buf)) r := fuse.ReadResultFd(uintptr(f.fd), off, len(buf))
return r, fuse.OK return r, OK
} }
func (f *loopbackFile) Write(ctx context.Context, data []byte, off int64) (uint32, fuse.Status) { func (f *loopbackFile) Write(ctx context.Context, data []byte, off int64) (uint32, syscall.Errno) {
n, err := syscall.Pwrite(f.fd, data, off) n, err := syscall.Pwrite(f.fd, data, off)
return uint32(n), fuse.ToStatus(err) return uint32(n), ToErrno(err)
} }
func (f *loopbackFile) Release(ctx context.Context) fuse.Status { func (f *loopbackFile) Release(ctx context.Context) syscall.Errno {
err := syscall.Close(f.fd) err := syscall.Close(f.fd)
return fuse.ToStatus(err) return ToErrno(err)
} }
func (f *loopbackFile) Flush(ctx context.Context) fuse.Status { func (f *loopbackFile) Flush(ctx context.Context) syscall.Errno {
// Since Flush() may be called for each dup'd fd, we don't // Since Flush() may be called for each dup'd fd, we don't
// want to really close the file, we just want to flush. This // want to really close the file, we just want to flush. This
// is achieved by closing a dup'd fd. // is achieved by closing a dup'd fd.
newFd, err := syscall.Dup(f.fd) newFd, err := syscall.Dup(f.fd)
if err != nil { if err != nil {
return fuse.ToStatus(err) return ToErrno(err)
} }
err = syscall.Close(newFd) err = syscall.Close(newFd)
return fuse.ToStatus(err) return ToErrno(err)
} }
func (f *loopbackFile) Fsync(ctx context.Context, flags uint32) (status fuse.Status) { func (f *loopbackFile) Fsync(ctx context.Context, flags uint32) (errno syscall.Errno) {
r := fuse.ToStatus(syscall.Fsync(f.fd)) r := ToErrno(syscall.Fsync(f.fd))
return r return r
} }
...@@ -64,23 +64,23 @@ const ( ...@@ -64,23 +64,23 @@ const (
_OFD_SETLKW = 38 _OFD_SETLKW = 38
) )
func (f *loopbackFile) GetLk(ctx context.Context, owner uint64, lk *fuse.FileLock, flags uint32, out *fuse.FileLock) (status fuse.Status) { func (f *loopbackFile) GetLk(ctx context.Context, owner uint64, lk *fuse.FileLock, flags uint32, out *fuse.FileLock) (errno syscall.Errno) {
flk := syscall.Flock_t{} flk := syscall.Flock_t{}
lk.ToFlockT(&flk) lk.ToFlockT(&flk)
status = fuse.ToStatus(syscall.FcntlFlock(uintptr(f.fd), _OFD_GETLK, &flk)) errno = ToErrno(syscall.FcntlFlock(uintptr(f.fd), _OFD_GETLK, &flk))
out.FromFlockT(&flk) out.FromFlockT(&flk)
return return
} }
func (f *loopbackFile) SetLk(ctx context.Context, owner uint64, lk *fuse.FileLock, flags uint32) (status fuse.Status) { func (f *loopbackFile) SetLk(ctx context.Context, owner uint64, lk *fuse.FileLock, flags uint32) (errno syscall.Errno) {
return f.setLock(ctx, owner, lk, flags, false) return f.setLock(ctx, owner, lk, flags, false)
} }
func (f *loopbackFile) SetLkw(ctx context.Context, owner uint64, lk *fuse.FileLock, flags uint32) (status fuse.Status) { func (f *loopbackFile) SetLkw(ctx context.Context, owner uint64, lk *fuse.FileLock, flags uint32) (errno syscall.Errno) {
return f.setLock(ctx, owner, lk, flags, true) return f.setLock(ctx, owner, lk, flags, true)
} }
func (f *loopbackFile) setLock(ctx context.Context, owner uint64, lk *fuse.FileLock, flags uint32, blocking bool) (status fuse.Status) { func (f *loopbackFile) setLock(ctx context.Context, owner uint64, lk *fuse.FileLock, flags uint32, blocking bool) (errno syscall.Errno) {
if (flags & fuse.FUSE_LK_FLOCK) != 0 { if (flags & fuse.FUSE_LK_FLOCK) != 0 {
var op int var op int
switch lk.Typ { switch lk.Typ {
...@@ -91,12 +91,12 @@ func (f *loopbackFile) setLock(ctx context.Context, owner uint64, lk *fuse.FileL ...@@ -91,12 +91,12 @@ func (f *loopbackFile) setLock(ctx context.Context, owner uint64, lk *fuse.FileL
case syscall.F_UNLCK: case syscall.F_UNLCK:
op = syscall.LOCK_UN op = syscall.LOCK_UN
default: default:
return fuse.EINVAL return syscall.EINVAL
} }
if !blocking { if !blocking {
op |= syscall.LOCK_NB op |= syscall.LOCK_NB
} }
return fuse.ToStatus(syscall.Flock(f.fd, op)) return ToErrno(syscall.Flock(f.fd, op))
} else { } else {
flk := syscall.Flock_t{} flk := syscall.Flock_t{}
lk.ToFlockT(&flk) lk.ToFlockT(&flk)
...@@ -106,24 +106,24 @@ func (f *loopbackFile) setLock(ctx context.Context, owner uint64, lk *fuse.FileL ...@@ -106,24 +106,24 @@ func (f *loopbackFile) setLock(ctx context.Context, owner uint64, lk *fuse.FileL
} else { } else {
op = _OFD_SETLK op = _OFD_SETLK
} }
return fuse.ToStatus(syscall.FcntlFlock(uintptr(f.fd), op, &flk)) return ToErrno(syscall.FcntlFlock(uintptr(f.fd), op, &flk))
} }
} }
func (f *loopbackFile) SetAttr(ctx context.Context, in *fuse.SetAttrIn, out *fuse.AttrOut) fuse.Status { func (f *loopbackFile) SetAttr(ctx context.Context, in *fuse.SetAttrIn, out *fuse.AttrOut) syscall.Errno {
if status := f.setAttr(ctx, in); !status.Ok() { if errno := f.setAttr(ctx, in); errno != 0 {
return status return errno
} }
return f.GetAttr(ctx, out) return f.GetAttr(ctx, out)
} }
func (f *loopbackFile) setAttr(ctx context.Context, in *fuse.SetAttrIn) fuse.Status { func (f *loopbackFile) setAttr(ctx context.Context, in *fuse.SetAttrIn) syscall.Errno {
var status fuse.Status var errno syscall.Errno
if mode, ok := in.GetMode(); ok { if mode, ok := in.GetMode(); ok {
status = fuse.ToStatus(syscall.Fchmod(f.fd, mode)) errno = ToErrno(syscall.Fchmod(f.fd, mode))
if !status.Ok() { if errno != 0 {
return status return errno
} }
} }
...@@ -139,9 +139,9 @@ func (f *loopbackFile) setAttr(ctx context.Context, in *fuse.SetAttrIn) fuse.Sta ...@@ -139,9 +139,9 @@ func (f *loopbackFile) setAttr(ctx context.Context, in *fuse.SetAttrIn) fuse.Sta
if gOk { if gOk {
gid = int(gid32) gid = int(gid32)
} }
status = fuse.ToStatus(syscall.Fchown(f.fd, uid, gid)) errno = ToErrno(syscall.Fchown(f.fd, uid, gid))
if !status.Ok() { if errno != 0 {
return status return errno
} }
} }
...@@ -157,33 +157,33 @@ func (f *loopbackFile) setAttr(ctx context.Context, in *fuse.SetAttrIn) fuse.Sta ...@@ -157,33 +157,33 @@ func (f *loopbackFile) setAttr(ctx context.Context, in *fuse.SetAttrIn) fuse.Sta
if !mok { if !mok {
mp = nil mp = nil
} }
status = f.utimens(ap, mp) errno = f.utimens(ap, mp)
if !status.Ok() { if errno != 0 {
return status return errno
} }
} }
if sz, ok := in.GetSize(); ok { if sz, ok := in.GetSize(); ok {
status = fuse.ToStatus(syscall.Ftruncate(f.fd, int64(sz))) errno = ToErrno(syscall.Ftruncate(f.fd, int64(sz)))
if !status.Ok() { if errno != 0 {
return status return errno
} }
} }
return fuse.OK return OK
} }
func (f *loopbackFile) GetAttr(ctx context.Context, a *fuse.AttrOut) fuse.Status { func (f *loopbackFile) GetAttr(ctx context.Context, a *fuse.AttrOut) syscall.Errno {
st := syscall.Stat_t{} st := syscall.Stat_t{}
err := syscall.Fstat(f.fd, &st) err := syscall.Fstat(f.fd, &st)
if err != nil { if err != nil {
return fuse.ToStatus(err) return ToErrno(err)
} }
a.FromStat(&st) a.FromStat(&st)
return fuse.OK return OK
} }
func (f *loopbackFile) Lseek(ctx context.Context, off uint64, whence uint32) (uint64, fuse.Status) { func (f *loopbackFile) Lseek(ctx context.Context, off uint64, whence uint32) (uint64, syscall.Errno) {
n, err := unix.Seek(f.fd, int64(off), int(whence)) n, err := unix.Seek(f.fd, int64(off), int(whence))
return uint64(n), fuse.ToStatus(err) return uint64(n), ToErrno(err)
} }
...@@ -6,15 +6,14 @@ package nodefs ...@@ -6,15 +6,14 @@ package nodefs
import ( import (
"context" "context"
"syscall"
"time" "time"
"github.com/hanwen/go-fuse/fuse"
) )
func (f *loopbackFile) Allocate(ctx context.Context, off uint64, sz uint64, mode uint32) fuse.Status { func (f *loopbackFile) Allocate(ctx context.Context, off uint64, sz uint64, mode uint32) syscall.Errno {
return fuse.ENOSYS return syscall.ENOSYS
} }
func (f *loopbackFile) Utimens(ctx context.Context, a *time.Time, m *time.Time) fuse.Status { func (f *loopbackFile) Utimens(ctx context.Context, a *time.Time, m *time.Time) syscall.Errno {
return fuse.ENOSYS return syscall.ENOSYS
} }
...@@ -12,19 +12,19 @@ import ( ...@@ -12,19 +12,19 @@ import (
"github.com/hanwen/go-fuse/fuse" "github.com/hanwen/go-fuse/fuse"
) )
func (f *loopbackFile) Allocate(ctx context.Context, off uint64, sz uint64, mode uint32) fuse.Status { func (f *loopbackFile) Allocate(ctx context.Context, off uint64, sz uint64, mode uint32) syscall.Errno {
err := syscall.Fallocate(f.fd, mode, int64(off), int64(sz)) err := syscall.Fallocate(f.fd, mode, int64(off), int64(sz))
if err != nil { if err != nil {
return fuse.ToStatus(err) return ToErrno(err)
} }
return fuse.OK return OK
} }
// Utimens - file handle based version of loopbackFileSystem.Utimens() // Utimens - file handle based version of loopbackFileSystem.Utimens()
func (f *loopbackFile) utimens(a *time.Time, m *time.Time) fuse.Status { func (f *loopbackFile) utimens(a *time.Time, m *time.Time) syscall.Errno {
var ts [2]syscall.Timespec var ts [2]syscall.Timespec
ts[0] = fuse.UtimeToTimespec(a) ts[0] = fuse.UtimeToTimespec(a)
ts[1] = fuse.UtimeToTimespec(m) ts[1] = fuse.UtimeToTimespec(m)
err := futimens(int(f.fd), &ts) err := futimens(int(f.fd), &ts)
return fuse.ToStatus(err) return ToErrno(err)
} }
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"sort" "sort"
"strings" "strings"
"sync" "sync"
"syscall"
"unsafe" "unsafe"
"github.com/hanwen/go-fuse/fuse" "github.com/hanwen/go-fuse/fuse"
...@@ -631,33 +632,34 @@ retry: ...@@ -631,33 +632,34 @@ retry:
// NotifyEntry notifies the kernel that data for a (directory, name) // NotifyEntry notifies the kernel that data for a (directory, name)
// tuple should be invalidated. On next access, a LOOKUP operation // tuple should be invalidated. On next access, a LOOKUP operation
// will be started. // will be started.
func (n *Inode) NotifyEntry(name string) fuse.Status { func (n *Inode) NotifyEntry(name string) syscall.Errno {
return n.bridge.server.EntryNotify(n.nodeAttr.Ino, name) status := n.bridge.server.EntryNotify(n.nodeAttr.Ino, name)
return syscall.Errno(status)
} }
// NotifyDelete notifies the kernel that the given inode was removed // NotifyDelete notifies the kernel that the given inode was removed
// from this directory as entry under the given name. It is equivalent // from this directory as entry under the given name. It is equivalent
// to NotifyEntry, but also sends an event to inotify watchers. // to NotifyEntry, but also sends an event to inotify watchers.
func (n *Inode) NotifyDelete(name string, child *Inode) fuse.Status { func (n *Inode) NotifyDelete(name string, child *Inode) syscall.Errno {
// XXX arg ordering? // XXX arg ordering?
return n.bridge.server.DeleteNotify(n.nodeAttr.Ino, child.nodeAttr.Ino, name) return syscall.Errno(n.bridge.server.DeleteNotify(n.nodeAttr.Ino, child.nodeAttr.Ino, name))
} }
// NotifyContent notifies the kernel that content under the given // NotifyContent notifies the kernel that content under the given
// inode should be flushed from buffers. // inode should be flushed from buffers.
func (n *Inode) NotifyContent(off, sz int64) fuse.Status { func (n *Inode) NotifyContent(off, sz int64) syscall.Errno {
// XXX how does this work for directories? // XXX how does this work for directories?
return n.bridge.server.InodeNotify(n.nodeAttr.Ino, off, sz) return syscall.Errno(n.bridge.server.InodeNotify(n.nodeAttr.Ino, off, sz))
} }
// WriteCache stores data in the kernel cache. // WriteCache stores data in the kernel cache.
func (n *Inode) WriteCache(offset int64, data []byte) fuse.Status { func (n *Inode) WriteCache(offset int64, data []byte) syscall.Errno {
return n.bridge.server.InodeNotifyStoreCache(n.nodeAttr.Ino, offset, data) return syscall.Errno(n.bridge.server.InodeNotifyStoreCache(n.nodeAttr.Ino, offset, data))
} }
// ReadCache reads data from the kernel cache. // ReadCache reads data from the kernel cache.
func (n *Inode) ReadCache(offset int64, dest []byte) (count int, status fuse.Status) { func (n *Inode) ReadCache(offset int64, dest []byte) (count int, errno syscall.Errno) {
return n.bridge.server.InodeRetrieveCache(n.nodeAttr.Ino, offset, dest) c, s := n.bridge.server.InodeRetrieveCache(n.nodeAttr.Ino, offset, dest)
return c, syscall.Errno(s)
} }
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"context" "context"
"os" "os"
"os/exec" "os/exec"
"syscall"
"testing" "testing"
"time" "time"
...@@ -25,24 +26,24 @@ type interruptOps struct { ...@@ -25,24 +26,24 @@ type interruptOps struct {
interrupted bool interrupted bool
} }
func (r *interruptRoot) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*Inode, fuse.Status) { func (r *interruptRoot) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*Inode, syscall.Errno) {
if name != "file" { if name != "file" {
return nil, fuse.ENOENT return nil, syscall.ENOENT
} }
ch := InodeOf(r).NewInode(ctx, &r.child, NodeAttr{ ch := InodeOf(r).NewInode(ctx, &r.child, NodeAttr{
Ino: 2, Ino: 2,
Gen: 1}) Gen: 1})
return ch, fuse.OK return ch, OK
} }
func (o *interruptOps) Open(ctx context.Context, flags uint32) (FileHandle, uint32, fuse.Status) { func (o *interruptOps) Open(ctx context.Context, flags uint32) (FileHandle, uint32, syscall.Errno) {
select { select {
case <-time.After(100 * time.Millisecond): case <-time.After(100 * time.Millisecond):
return nil, 0, fuse.EIO return nil, 0, syscall.EIO
case <-ctx.Done(): case <-ctx.Done():
o.interrupted = true o.interrupted = true
return nil, 0, fuse.EINTR return nil, 0, syscall.EINTR
} }
} }
......
...@@ -27,25 +27,25 @@ func (n *loopbackRoot) newLoopbackNode() *loopbackNode { ...@@ -27,25 +27,25 @@ func (n *loopbackRoot) newLoopbackNode() *loopbackNode {
} }
} }
func (n *loopbackNode) StatFs(ctx context.Context, out *fuse.StatfsOut) fuse.Status { func (n *loopbackNode) StatFs(ctx context.Context, out *fuse.StatfsOut) syscall.Errno {
s := syscall.Statfs_t{} s := syscall.Statfs_t{}
err := syscall.Statfs(n.path(), &s) err := syscall.Statfs(n.path(), &s)
if err != nil { if err != nil {
return fuse.ToStatus(err) return ToErrno(err)
} }
out.FromStatfsT(&s) out.FromStatfsT(&s)
return fuse.OK return OK
} }
func (n *loopbackRoot) GetAttr(ctx context.Context, out *fuse.AttrOut) fuse.Status { func (n *loopbackRoot) GetAttr(ctx context.Context, out *fuse.AttrOut) syscall.Errno {
var err error = nil var err error = nil
st := syscall.Stat_t{} st := syscall.Stat_t{}
err = syscall.Stat(n.root, &st) err = syscall.Stat(n.root, &st)
if err != nil { if err != nil {
return fuse.ToStatus(err) return ToErrno(err)
} }
out.FromStat(&st) out.FromStat(&st)
return fuse.OK return OK
} }
type loopbackNode struct { type loopbackNode struct {
...@@ -59,31 +59,31 @@ func (n *loopbackNode) path() string { ...@@ -59,31 +59,31 @@ func (n *loopbackNode) path() string {
return filepath.Join(n.rootNode.root, path) return filepath.Join(n.rootNode.root, path)
} }
func (n *loopbackNode) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*Inode, fuse.Status) { func (n *loopbackNode) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*Inode, syscall.Errno) {
p := filepath.Join(n.path(), name) p := filepath.Join(n.path(), name)
st := syscall.Stat_t{} st := syscall.Stat_t{}
err := syscall.Lstat(p, &st) err := syscall.Lstat(p, &st)
if err != nil { if err != nil {
return nil, fuse.ToStatus(err) return nil, ToErrno(err)
} }
out.Attr.FromStat(&st) out.Attr.FromStat(&st)
node := n.rootNode.newLoopbackNode() node := n.rootNode.newLoopbackNode()
ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st)) ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st))
return ch, fuse.OK return ch, 0
} }
func (n *loopbackNode) Mknod(ctx context.Context, name string, mode, rdev uint32, out *fuse.EntryOut) (*Inode, fuse.Status) { func (n *loopbackNode) Mknod(ctx context.Context, name string, mode, rdev uint32, out *fuse.EntryOut) (*Inode, syscall.Errno) {
p := filepath.Join(n.path(), name) p := filepath.Join(n.path(), name)
err := syscall.Mknod(p, mode, int(rdev)) err := syscall.Mknod(p, mode, int(rdev))
if err != nil { if err != nil {
return nil, fuse.ToStatus(err) return nil, ToErrno(err)
} }
st := syscall.Stat_t{} st := syscall.Stat_t{}
if err := syscall.Lstat(p, &st); err != nil { if err := syscall.Lstat(p, &st); err != nil {
syscall.Rmdir(p) syscall.Rmdir(p)
return nil, fuse.ToStatus(err) return nil, ToErrno(err)
} }
out.Attr.FromStat(&st) out.Attr.FromStat(&st)
...@@ -91,19 +91,19 @@ func (n *loopbackNode) Mknod(ctx context.Context, name string, mode, rdev uint32 ...@@ -91,19 +91,19 @@ func (n *loopbackNode) Mknod(ctx context.Context, name string, mode, rdev uint32
node := n.rootNode.newLoopbackNode() node := n.rootNode.newLoopbackNode()
ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st)) ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st))
return ch, fuse.OK return ch, 0
} }
func (n *loopbackNode) Mkdir(ctx context.Context, name string, mode uint32, out *fuse.EntryOut) (*Inode, fuse.Status) { func (n *loopbackNode) Mkdir(ctx context.Context, name string, mode uint32, out *fuse.EntryOut) (*Inode, syscall.Errno) {
p := filepath.Join(n.path(), name) p := filepath.Join(n.path(), name)
err := os.Mkdir(p, os.FileMode(mode)) err := os.Mkdir(p, os.FileMode(mode))
if err != nil { if err != nil {
return nil, fuse.ToStatus(err) return nil, ToErrno(err)
} }
st := syscall.Stat_t{} st := syscall.Stat_t{}
if err := syscall.Lstat(p, &st); err != nil { if err := syscall.Lstat(p, &st); err != nil {
syscall.Rmdir(p) syscall.Rmdir(p)
return nil, fuse.ToStatus(err) return nil, ToErrno(err)
} }
out.Attr.FromStat(&st) out.Attr.FromStat(&st)
...@@ -111,19 +111,19 @@ func (n *loopbackNode) Mkdir(ctx context.Context, name string, mode uint32, out ...@@ -111,19 +111,19 @@ func (n *loopbackNode) Mkdir(ctx context.Context, name string, mode uint32, out
node := n.rootNode.newLoopbackNode() node := n.rootNode.newLoopbackNode()
ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st)) ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st))
return ch, fuse.OK return ch, 0
} }
func (n *loopbackNode) Rmdir(ctx context.Context, name string) fuse.Status { func (n *loopbackNode) Rmdir(ctx context.Context, name string) syscall.Errno {
p := filepath.Join(n.path(), name) p := filepath.Join(n.path(), name)
err := syscall.Rmdir(p) err := syscall.Rmdir(p)
return fuse.ToStatus(err) return ToErrno(err)
} }
func (n *loopbackNode) Unlink(ctx context.Context, name string) fuse.Status { func (n *loopbackNode) Unlink(ctx context.Context, name string) syscall.Errno {
p := filepath.Join(n.path(), name) p := filepath.Join(n.path(), name)
err := syscall.Unlink(p) err := syscall.Unlink(p)
return fuse.ToStatus(err) return ToErrno(err)
} }
func toLoopbackNode(op Operations) *loopbackNode { func toLoopbackNode(op Operations) *loopbackNode {
...@@ -133,7 +133,7 @@ func toLoopbackNode(op Operations) *loopbackNode { ...@@ -133,7 +133,7 @@ func toLoopbackNode(op Operations) *loopbackNode {
return op.(*loopbackNode) return op.(*loopbackNode)
} }
func (n *loopbackNode) Rename(ctx context.Context, name string, newParent Operations, newName string, flags uint32) fuse.Status { func (n *loopbackNode) Rename(ctx context.Context, name string, newParent Operations, newName string, flags uint32) syscall.Errno {
newParentLoopback := toLoopbackNode(newParent) newParentLoopback := toLoopbackNode(newParent)
if flags&unix.RENAME_EXCHANGE != 0 { if flags&unix.RENAME_EXCHANGE != 0 {
return n.renameExchange(name, newParentLoopback, newName) return n.renameExchange(name, newParentLoopback, newName)
...@@ -143,7 +143,7 @@ func (n *loopbackNode) Rename(ctx context.Context, name string, newParent Operat ...@@ -143,7 +143,7 @@ func (n *loopbackNode) Rename(ctx context.Context, name string, newParent Operat
p2 := filepath.Join(newParentLoopback.path(), newName) p2 := filepath.Join(newParentLoopback.path(), newName)
err := os.Rename(p1, p2) err := os.Rename(p1, p2)
return fuse.ToStatus(err) return ToErrno(err)
} }
func (r *loopbackRoot) idFromStat(st *syscall.Stat_t) NodeAttr { func (r *loopbackRoot) idFromStat(st *syscall.Stat_t) NodeAttr {
...@@ -165,104 +165,104 @@ func (r *loopbackRoot) idFromStat(st *syscall.Stat_t) NodeAttr { ...@@ -165,104 +165,104 @@ func (r *loopbackRoot) idFromStat(st *syscall.Stat_t) NodeAttr {
} }
} }
func (n *loopbackNode) Create(ctx context.Context, name string, flags uint32, mode uint32) (inode *Inode, fh FileHandle, fuseFlags uint32, status fuse.Status) { func (n *loopbackNode) Create(ctx context.Context, name string, flags uint32, mode uint32) (inode *Inode, fh FileHandle, fuseFlags uint32, errno syscall.Errno) {
p := filepath.Join(n.path(), name) p := filepath.Join(n.path(), name)
fd, err := syscall.Open(p, int(flags)|os.O_CREATE, mode) fd, err := syscall.Open(p, int(flags)|os.O_CREATE, mode)
if err != nil { if err != nil {
return nil, nil, 0, fuse.ToStatus(err) return nil, nil, 0, ToErrno(err)
} }
st := syscall.Stat_t{} st := syscall.Stat_t{}
if err := syscall.Fstat(fd, &st); err != nil { if err := syscall.Fstat(fd, &st); err != nil {
syscall.Close(fd) syscall.Close(fd)
return nil, nil, 0, fuse.ToStatus(err) return nil, nil, 0, ToErrno(err)
} }
node := n.rootNode.newLoopbackNode() node := n.rootNode.newLoopbackNode()
ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st)) ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st))
lf := NewLoopbackFile(fd) lf := NewLoopbackFile(fd)
return ch, lf, 0, fuse.OK return ch, lf, 0, 0
} }
func (n *loopbackNode) Symlink(ctx context.Context, target, name string, out *fuse.EntryOut) (*Inode, fuse.Status) { func (n *loopbackNode) Symlink(ctx context.Context, target, name string, out *fuse.EntryOut) (*Inode, syscall.Errno) {
p := filepath.Join(n.path(), name) p := filepath.Join(n.path(), name)
err := syscall.Symlink(target, p) err := syscall.Symlink(target, p)
if err != nil { if err != nil {
return nil, fuse.ToStatus(err) return nil, ToErrno(err)
} }
st := syscall.Stat_t{} st := syscall.Stat_t{}
if syscall.Lstat(p, &st); err != nil { if syscall.Lstat(p, &st); err != nil {
syscall.Unlink(p) syscall.Unlink(p)
return nil, fuse.ToStatus(err) return nil, ToErrno(err)
} }
node := n.rootNode.newLoopbackNode() node := n.rootNode.newLoopbackNode()
ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st)) ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st))
out.Attr.FromStat(&st) out.Attr.FromStat(&st)
return ch, fuse.OK return ch, 0
} }
func (n *loopbackNode) Link(ctx context.Context, target Operations, name string, out *fuse.EntryOut) (*Inode, fuse.Status) { func (n *loopbackNode) Link(ctx context.Context, target Operations, name string, out *fuse.EntryOut) (*Inode, syscall.Errno) {
p := filepath.Join(n.path(), name) p := filepath.Join(n.path(), name)
targetNode := toLoopbackNode(target) targetNode := toLoopbackNode(target)
err := syscall.Link(targetNode.path(), p) err := syscall.Link(targetNode.path(), p)
if err != nil { if err != nil {
return nil, fuse.ToStatus(err) return nil, ToErrno(err)
} }
st := syscall.Stat_t{} st := syscall.Stat_t{}
if syscall.Lstat(p, &st); err != nil { if syscall.Lstat(p, &st); err != nil {
syscall.Unlink(p) syscall.Unlink(p)
return nil, fuse.ToStatus(err) return nil, ToErrno(err)
} }
node := n.rootNode.newLoopbackNode() node := n.rootNode.newLoopbackNode()
ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st)) ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st))
out.Attr.FromStat(&st) out.Attr.FromStat(&st)
return ch, fuse.OK return ch, 0
} }
func (n *loopbackNode) Readlink(ctx context.Context) ([]byte, fuse.Status) { func (n *loopbackNode) Readlink(ctx context.Context) ([]byte, syscall.Errno) {
p := n.path() p := n.path()
for l := 256; ; l *= 2 { for l := 256; ; l *= 2 {
buf := make([]byte, l) buf := make([]byte, l)
sz, err := syscall.Readlink(p, buf) sz, err := syscall.Readlink(p, buf)
if err != nil { if err != nil {
return nil, fuse.ToStatus(err) return nil, ToErrno(err)
} }
if sz < len(buf) { if sz < len(buf) {
return buf[:sz], fuse.OK return buf[:sz], 0
} }
} }
} }
func (n *loopbackNode) Open(ctx context.Context, flags uint32) (fh FileHandle, fuseFlags uint32, status fuse.Status) { func (n *loopbackNode) Open(ctx context.Context, flags uint32) (fh FileHandle, fuseFlags uint32, errno syscall.Errno) {
p := n.path() p := n.path()
f, err := syscall.Open(p, int(flags), 0) f, err := syscall.Open(p, int(flags), 0)
if err != nil { if err != nil {
return nil, 0, fuse.ToStatus(err) return nil, 0, ToErrno(err)
} }
lf := NewLoopbackFile(f) lf := NewLoopbackFile(f)
return lf, 0, fuse.OK return lf, 0, 0
} }
func (n *loopbackNode) OpenDir(ctx context.Context) fuse.Status { func (n *loopbackNode) OpenDir(ctx context.Context) syscall.Errno {
fd, err := syscall.Open(n.path(), syscall.O_DIRECTORY, 0755) fd, err := syscall.Open(n.path(), syscall.O_DIRECTORY, 0755)
if err != nil { if err != nil {
return fuse.ToStatus(err) return ToErrno(err)
} }
syscall.Close(fd) syscall.Close(fd)
return fuse.OK return OK
} }
func (n *loopbackNode) ReadDir(ctx context.Context) (DirStream, fuse.Status) { func (n *loopbackNode) ReadDir(ctx context.Context) (DirStream, syscall.Errno) {
return NewLoopbackDirStream(n.path()) return NewLoopbackDirStream(n.path())
} }
func (n *loopbackNode) FGetAttr(ctx context.Context, f FileHandle, out *fuse.AttrOut) fuse.Status { func (n *loopbackNode) FGetAttr(ctx context.Context, f FileHandle, out *fuse.AttrOut) syscall.Errno {
if f != nil { if f != nil {
return f.GetAttr(ctx, out) return f.GetAttr(ctx, out)
} }
...@@ -273,28 +273,28 @@ func (n *loopbackNode) FGetAttr(ctx context.Context, f FileHandle, out *fuse.Att ...@@ -273,28 +273,28 @@ func (n *loopbackNode) FGetAttr(ctx context.Context, f FileHandle, out *fuse.Att
st := syscall.Stat_t{} st := syscall.Stat_t{}
err = syscall.Lstat(p, &st) err = syscall.Lstat(p, &st)
if err != nil { if err != nil {
return fuse.ToStatus(err) return ToErrno(err)
} }
out.FromStat(&st) out.FromStat(&st)
return fuse.OK return OK
} }
func (n *loopbackNode) CopyFileRange(ctx context.Context, fhIn FileHandle, func (n *loopbackNode) CopyFileRange(ctx context.Context, fhIn FileHandle,
offIn uint64, out *Inode, fhOut FileHandle, offOut uint64, offIn uint64, out *Inode, fhOut FileHandle, offOut uint64,
len uint64, flags uint64) (uint32, fuse.Status) { len uint64, flags uint64) (uint32, syscall.Errno) {
lfIn, ok := fhIn.(*loopbackFile) lfIn, ok := fhIn.(*loopbackFile)
if !ok { if !ok {
return 0, fuse.ENOTSUP return 0, syscall.ENOTSUP
} }
lfOut, ok := fhOut.(*loopbackFile) lfOut, ok := fhOut.(*loopbackFile)
if !ok { if !ok {
return 0, fuse.ENOTSUP return 0, syscall.ENOTSUP
} }
signedOffIn := int64(offIn) signedOffIn := int64(offIn)
signedOffOut := int64(offOut) signedOffOut := int64(offOut)
count, err := unix.CopyFileRange(lfIn.fd, &signedOffIn, lfOut.fd, &signedOffOut, int(len), int(flags)) count, err := unix.CopyFileRange(lfIn.fd, &signedOffIn, lfOut.fd, &signedOffOut, int(len), int(flags))
return uint32(count), fuse.ToStatus(err) return uint32(count), ToErrno(err)
} }
// NewLoopback returns a root node for a loopback file system whose // NewLoopback returns a root node for a loopback file system whose
......
...@@ -8,55 +8,54 @@ import ( ...@@ -8,55 +8,54 @@ import (
"context" "context"
"syscall" "syscall"
"github.com/hanwen/go-fuse/fuse"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
func (n *loopbackNode) GetXAttr(ctx context.Context, attr string, dest []byte) (uint32, fuse.Status) { func (n *loopbackNode) GetXAttr(ctx context.Context, attr string, dest []byte) (uint32, syscall.Errno) {
sz, err := syscall.Getxattr(n.path(), attr, dest) sz, err := syscall.Getxattr(n.path(), attr, dest)
return uint32(sz), fuse.ToStatus(err) return uint32(sz), ToErrno(err)
} }
func (n *loopbackNode) SetXAttr(ctx context.Context, attr string, data []byte, flags uint32) fuse.Status { func (n *loopbackNode) SetXAttr(ctx context.Context, attr string, data []byte, flags uint32) syscall.Errno {
err := syscall.Setxattr(n.path(), attr, data, int(flags)) err := syscall.Setxattr(n.path(), attr, data, int(flags))
return fuse.ToStatus(err) return ToErrno(err)
} }
func (n *loopbackNode) RemoveXAttr(ctx context.Context, attr string) fuse.Status { func (n *loopbackNode) RemoveXAttr(ctx context.Context, attr string) syscall.Errno {
err := syscall.Removexattr(n.path(), attr) err := syscall.Removexattr(n.path(), attr)
return fuse.ToStatus(err) return ToErrno(err)
} }
func (n *loopbackNode) ListXAttr(ctx context.Context, dest []byte) (uint32, fuse.Status) { func (n *loopbackNode) ListXAttr(ctx context.Context, dest []byte) (uint32, syscall.Errno) {
sz, err := syscall.Listxattr(n.path(), dest) sz, err := syscall.Listxattr(n.path(), dest)
return uint32(sz), fuse.ToStatus(err) return uint32(sz), ToErrno(err)
} }
func (n *loopbackNode) renameExchange(name string, newparent *loopbackNode, newName string) fuse.Status { func (n *loopbackNode) renameExchange(name string, newparent *loopbackNode, newName string) syscall.Errno {
fd1, err := syscall.Open(n.path(), syscall.O_DIRECTORY, 0) fd1, err := syscall.Open(n.path(), syscall.O_DIRECTORY, 0)
if err != nil { if err != nil {
return fuse.ToStatus(err) return ToErrno(err)
} }
defer syscall.Close(fd1) defer syscall.Close(fd1)
fd2, err := syscall.Open(newparent.path(), syscall.O_DIRECTORY, 0) fd2, err := syscall.Open(newparent.path(), syscall.O_DIRECTORY, 0)
defer syscall.Close(fd2) defer syscall.Close(fd2)
if err != nil { if err != nil {
return fuse.ToStatus(err) return ToErrno(err)
} }
var st syscall.Stat_t var st syscall.Stat_t
if err := syscall.Fstat(fd1, &st); err != nil { if err := syscall.Fstat(fd1, &st); err != nil {
return fuse.ToStatus(err) return ToErrno(err)
} }
if !n.Inode().IsRoot() && InodeOf(n).NodeAttr().Ino != n.rootNode.idFromStat(&st).Ino { if !n.Inode().IsRoot() && InodeOf(n).NodeAttr().Ino != n.rootNode.idFromStat(&st).Ino {
return fuse.EBUSY return syscall.EBUSY
} }
if err := syscall.Fstat(fd2, &st); err != nil { if err := syscall.Fstat(fd2, &st); err != nil {
return fuse.ToStatus(err) return ToErrno(err)
} }
if !newparent.Inode().IsRoot() && InodeOf(newparent).NodeAttr().Ino != n.rootNode.idFromStat(&st).Ino { if !newparent.Inode().IsRoot() && InodeOf(newparent).NodeAttr().Ino != n.rootNode.idFromStat(&st).Ino {
return fuse.EBUSY return syscall.EBUSY
} }
return fuse.ToStatus(unix.Renameat2(fd1, name, fd2, newName, unix.RENAME_EXCHANGE)) return ToErrno(unix.Renameat2(fd1, name, fd2, newName, unix.RENAME_EXCHANGE))
} }
...@@ -525,8 +525,8 @@ func TestNotifyEntry(t *testing.T) { ...@@ -525,8 +525,8 @@ func TestNotifyEntry(t *testing.T) {
t.Fatalf("got after %#v, want %#v", after, st) t.Fatalf("got after %#v, want %#v", after, st)
} }
if code := tc.loopback.Inode().NotifyEntry("file"); !code.Ok() { if errno := tc.loopback.Inode().NotifyEntry("file"); errno != 0 {
t.Errorf("notify failed: %v", code) t.Errorf("notify failed: %v", errno)
} }
if err := syscall.Lstat(fn, &after); err != syscall.ENOENT { if err := syscall.Lstat(fn, &after); err != syscall.ENOENT {
......
...@@ -14,6 +14,7 @@ import ( ...@@ -14,6 +14,7 @@ import (
"reflect" "reflect"
"strings" "strings"
"sync" "sync"
"syscall"
"testing" "testing"
"github.com/hanwen/go-fuse/fuse" "github.com/hanwen/go-fuse/fuse"
...@@ -116,23 +117,23 @@ var _ = (FileOperations)((*zipFile)(nil)) ...@@ -116,23 +117,23 @@ var _ = (FileOperations)((*zipFile)(nil))
// GetAttr sets the minimum, which is the size. A more full-featured // GetAttr sets the minimum, which is the size. A more full-featured
// FS would also set timestamps and permissions. // FS would also set timestamps and permissions.
func (zf *zipFile) GetAttr(ctx context.Context, out *fuse.AttrOut) fuse.Status { func (zf *zipFile) GetAttr(ctx context.Context, out *fuse.AttrOut) syscall.Errno {
out.Size = zf.file.UncompressedSize64 out.Size = zf.file.UncompressedSize64
return fuse.OK return OK
} }
// Open lazily unpacks zip data // Open lazily unpacks zip data
func (zf *zipFile) Open(ctx context.Context, flags uint32) (FileHandle, uint32, fuse.Status) { func (zf *zipFile) Open(ctx context.Context, flags uint32) (FileHandle, uint32, syscall.Errno) {
zf.mu.Lock() zf.mu.Lock()
defer zf.mu.Unlock() defer zf.mu.Unlock()
if zf.data == nil { if zf.data == nil {
rc, err := zf.file.Open() rc, err := zf.file.Open()
if err != nil { if err != nil {
return nil, 0, fuse.EIO return nil, 0, syscall.EIO
} }
content, err := ioutil.ReadAll(rc) content, err := ioutil.ReadAll(rc)
if err != nil { if err != nil {
return nil, 0, fuse.EIO return nil, 0, syscall.EIO
} }
zf.data = content zf.data = content
...@@ -141,16 +142,16 @@ func (zf *zipFile) Open(ctx context.Context, flags uint32) (FileHandle, uint32, ...@@ -141,16 +142,16 @@ func (zf *zipFile) Open(ctx context.Context, flags uint32) (FileHandle, uint32,
// We don't return a filehandle since we don't really need // We don't return a filehandle since we don't really need
// one. The file content is immutable, so hint the kernel to // one. The file content is immutable, so hint the kernel to
// cache the data. // cache the data.
return nil, fuse.FOPEN_KEEP_CACHE, fuse.OK return nil, fuse.FOPEN_KEEP_CACHE, OK
} }
// Read simply returns the data that was already unpacked in the Open call // Read simply returns the data that was already unpacked in the Open call
func (zf *zipFile) Read(ctx context.Context, f FileHandle, dest []byte, off int64) (fuse.ReadResult, fuse.Status) { func (zf *zipFile) Read(ctx context.Context, f FileHandle, dest []byte, off int64) (fuse.ReadResult, syscall.Errno) {
end := int(off) + len(dest) end := int(off) + len(dest)
if end > len(zf.data) { if end > len(zf.data) {
end = len(zf.data) end = len(zf.data)
} }
return fuse.ReadResultData(zf.data[off:end]), fuse.OK return fuse.ReadResultData(zf.data[off:end]), OK
} }
// zipRoot is the root of the Zip filesystem. Its only functionality // zipRoot is the root of the Zip filesystem. Its only functionality
......
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