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 (
"io/ioutil"
"os"
"sync"
"syscall"
"testing"
"github.com/hanwen/go-fuse/fuse"
......@@ -33,31 +34,31 @@ func (f *keepCacheFile) setContent(delta int) {
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
if f.keepCache {
fl = fuse.FOPEN_KEEP_CACHE
}
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()
defer f.mu.Unlock()
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.mu.Lock()
defer f.mu.Unlock()
return fuse.ReadResultData(f.content[off:]), fuse.OK
return fuse.ReadResultData(f.content[off:]), OK
}
type keepCacheRoot struct {
......@@ -112,7 +113,7 @@ func TestKeepCache(t *testing.T) {
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)
}
......
// 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 {
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))
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)
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
......@@ -45,8 +45,8 @@ type dioFile struct {
DefaultOperations
}
func (f *dioFile) Open(ctx context.Context, flags uint32) (fh FileHandle, fuseFlags uint32, status fuse.Status) {
return &dioFH{}, fuse.FOPEN_DIRECT_IO, fuse.OK
func (f *dioFile) Open(ctx context.Context, flags uint32) (fh FileHandle, fuseFlags uint32, errno syscall.Errno) {
return &dioFH{}, fuse.FOPEN_DIRECT_IO, OK
}
func TestDirectIO(t *testing.T) {
......
......@@ -5,6 +5,8 @@
package nodefs
import (
"syscall"
"github.com/hanwen/go-fuse/fuse"
)
......@@ -16,10 +18,10 @@ func (a *dirArray) HasNext() bool {
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]
a.entries = a.entries[1:]
return e, fuse.OK
return e, 0
}
func (a *dirArray) Close() {
......
......@@ -7,14 +7,15 @@ package nodefs
import (
"io"
"os"
"syscall"
"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)
if err != nil {
return nil, fuse.ToStatus(err)
return nil, ToErrno(err)
}
defer f.Close()
......@@ -39,9 +40,9 @@ func NewLoopbackDirStream(nm string) (DirStream, fuse.Status) {
}
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 {
}
// 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)
if err != nil {
return nil, fuse.ToStatus(err)
return nil, ToErrno(err)
}
ds := &loopbackDirStream{
......@@ -29,11 +29,11 @@ func NewLoopbackDirStream(name string) (DirStream, fuse.Status) {
fd: fd,
}
if err := ds.load(); !err.Ok() {
if err := ds.load(); err != 0 {
ds.Close()
return nil, err
}
return ds, fuse.OK
return ds, OK
}
func (ds *loopbackDirStream) Close() {
......@@ -44,7 +44,7 @@ func (ds *loopbackDirStream) HasNext() bool {
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]))
nameBytes := ds.todo[unsafe.Offsetof(syscall.Dirent{}.Name):de.Reclen]
......@@ -64,15 +64,15 @@ func (ds *loopbackDirStream) Next() (fuse.DirEntry, fuse.Status) {
return result, ds.load()
}
func (ds *loopbackDirStream) load() fuse.Status {
func (ds *loopbackDirStream) load() syscall.Errno {
if len(ds.todo) > 0 {
return fuse.OK
return OK
}
n, err := syscall.Getdents(ds.fd, ds.buf)
if err != nil {
return fuse.ToStatus(err)
return ToErrno(err)
}
ds.todo = ds.buf[:n]
return fuse.OK
return OK
}
......@@ -24,36 +24,36 @@ type loopbackFile struct {
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))
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)
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)
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
// want to really close the file, we just want to flush. This
// is achieved by closing a dup'd fd.
newFd, err := syscall.Dup(f.fd)
if err != nil {
return fuse.ToStatus(err)
return ToErrno(err)
}
err = syscall.Close(newFd)
return fuse.ToStatus(err)
return ToErrno(err)
}
func (f *loopbackFile) Fsync(ctx context.Context, flags uint32) (status fuse.Status) {
r := fuse.ToStatus(syscall.Fsync(f.fd))
func (f *loopbackFile) Fsync(ctx context.Context, flags uint32) (errno syscall.Errno) {
r := ToErrno(syscall.Fsync(f.fd))
return r
}
......@@ -64,23 +64,23 @@ const (
_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{}
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)
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)
}
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)
}
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 {
var op int
switch lk.Typ {
......@@ -91,12 +91,12 @@ func (f *loopbackFile) setLock(ctx context.Context, owner uint64, lk *fuse.FileL
case syscall.F_UNLCK:
op = syscall.LOCK_UN
default:
return fuse.EINVAL
return syscall.EINVAL
}
if !blocking {
op |= syscall.LOCK_NB
}
return fuse.ToStatus(syscall.Flock(f.fd, op))
return ToErrno(syscall.Flock(f.fd, op))
} else {
flk := syscall.Flock_t{}
lk.ToFlockT(&flk)
......@@ -106,24 +106,24 @@ func (f *loopbackFile) setLock(ctx context.Context, owner uint64, lk *fuse.FileL
} else {
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 {
if status := f.setAttr(ctx, in); !status.Ok() {
return status
func (f *loopbackFile) SetAttr(ctx context.Context, in *fuse.SetAttrIn, out *fuse.AttrOut) syscall.Errno {
if errno := f.setAttr(ctx, in); errno != 0 {
return errno
}
return f.GetAttr(ctx, out)
}
func (f *loopbackFile) setAttr(ctx context.Context, in *fuse.SetAttrIn) fuse.Status {
var status fuse.Status
func (f *loopbackFile) setAttr(ctx context.Context, in *fuse.SetAttrIn) syscall.Errno {
var errno syscall.Errno
if mode, ok := in.GetMode(); ok {
status = fuse.ToStatus(syscall.Fchmod(f.fd, mode))
if !status.Ok() {
return status
errno = ToErrno(syscall.Fchmod(f.fd, mode))
if errno != 0 {
return errno
}
}
......@@ -139,9 +139,9 @@ func (f *loopbackFile) setAttr(ctx context.Context, in *fuse.SetAttrIn) fuse.Sta
if gOk {
gid = int(gid32)
}
status = fuse.ToStatus(syscall.Fchown(f.fd, uid, gid))
if !status.Ok() {
return status
errno = ToErrno(syscall.Fchown(f.fd, uid, gid))
if errno != 0 {
return errno
}
}
......@@ -157,33 +157,33 @@ func (f *loopbackFile) setAttr(ctx context.Context, in *fuse.SetAttrIn) fuse.Sta
if !mok {
mp = nil
}
status = f.utimens(ap, mp)
if !status.Ok() {
return status
errno = f.utimens(ap, mp)
if errno != 0 {
return errno
}
}
if sz, ok := in.GetSize(); ok {
status = fuse.ToStatus(syscall.Ftruncate(f.fd, int64(sz)))
if !status.Ok() {
return status
errno = ToErrno(syscall.Ftruncate(f.fd, int64(sz)))
if errno != 0 {
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{}
err := syscall.Fstat(f.fd, &st)
if err != nil {
return fuse.ToStatus(err)
return ToErrno(err)
}
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))
return uint64(n), fuse.ToStatus(err)
return uint64(n), ToErrno(err)
}
......@@ -6,15 +6,14 @@ package nodefs
import (
"context"
"syscall"
"time"
"github.com/hanwen/go-fuse/fuse"
)
func (f *loopbackFile) Allocate(ctx context.Context, off uint64, sz uint64, mode uint32) fuse.Status {
return fuse.ENOSYS
func (f *loopbackFile) Allocate(ctx context.Context, off uint64, sz uint64, mode uint32) syscall.Errno {
return syscall.ENOSYS
}
func (f *loopbackFile) Utimens(ctx context.Context, a *time.Time, m *time.Time) fuse.Status {
return fuse.ENOSYS
func (f *loopbackFile) Utimens(ctx context.Context, a *time.Time, m *time.Time) syscall.Errno {
return syscall.ENOSYS
}
......@@ -12,19 +12,19 @@ import (
"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))
if err != nil {
return fuse.ToStatus(err)
return ToErrno(err)
}
return fuse.OK
return OK
}
// 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
ts[0] = fuse.UtimeToTimespec(a)
ts[1] = fuse.UtimeToTimespec(m)
err := futimens(int(f.fd), &ts)
return fuse.ToStatus(err)
return ToErrno(err)
}
......@@ -11,6 +11,7 @@ import (
"sort"
"strings"
"sync"
"syscall"
"unsafe"
"github.com/hanwen/go-fuse/fuse"
......@@ -631,33 +632,34 @@ retry:
// NotifyEntry notifies the kernel that data for a (directory, name)
// tuple should be invalidated. On next access, a LOOKUP operation
// will be started.
func (n *Inode) NotifyEntry(name string) fuse.Status {
return n.bridge.server.EntryNotify(n.nodeAttr.Ino, name)
func (n *Inode) NotifyEntry(name string) syscall.Errno {
status := n.bridge.server.EntryNotify(n.nodeAttr.Ino, name)
return syscall.Errno(status)
}
// NotifyDelete notifies the kernel that the given inode was removed
// from this directory as entry under the given name. It is equivalent
// 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?
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
// 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?
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.
func (n *Inode) WriteCache(offset int64, data []byte) fuse.Status {
return n.bridge.server.InodeNotifyStoreCache(n.nodeAttr.Ino, offset, data)
func (n *Inode) WriteCache(offset int64, data []byte) syscall.Errno {
return syscall.Errno(n.bridge.server.InodeNotifyStoreCache(n.nodeAttr.Ino, offset, data))
}
// ReadCache reads data from the kernel cache.
func (n *Inode) ReadCache(offset int64, dest []byte) (count int, status fuse.Status) {
return n.bridge.server.InodeRetrieveCache(n.nodeAttr.Ino, offset, dest)
func (n *Inode) ReadCache(offset int64, dest []byte) (count int, errno syscall.Errno) {
c, s := n.bridge.server.InodeRetrieveCache(n.nodeAttr.Ino, offset, dest)
return c, syscall.Errno(s)
}
......@@ -8,6 +8,7 @@ import (
"context"
"os"
"os/exec"
"syscall"
"testing"
"time"
......@@ -25,24 +26,24 @@ type interruptOps struct {
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" {
return nil, fuse.ENOENT
return nil, syscall.ENOENT
}
ch := InodeOf(r).NewInode(ctx, &r.child, NodeAttr{
Ino: 2,
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 {
case <-time.After(100 * time.Millisecond):
return nil, 0, fuse.EIO
return nil, 0, syscall.EIO
case <-ctx.Done():
o.interrupted = true
return nil, 0, fuse.EINTR
return nil, 0, syscall.EINTR
}
}
......
......@@ -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{}
err := syscall.Statfs(n.path(), &s)
if err != nil {
return fuse.ToStatus(err)
return ToErrno(err)
}
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
st := syscall.Stat_t{}
err = syscall.Stat(n.root, &st)
if err != nil {
return fuse.ToStatus(err)
return ToErrno(err)
}
out.FromStat(&st)
return fuse.OK
return OK
}
type loopbackNode struct {
......@@ -59,31 +59,31 @@ func (n *loopbackNode) path() string {
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)
st := syscall.Stat_t{}
err := syscall.Lstat(p, &st)
if err != nil {
return nil, fuse.ToStatus(err)
return nil, ToErrno(err)
}
out.Attr.FromStat(&st)
node := n.rootNode.newLoopbackNode()
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)
err := syscall.Mknod(p, mode, int(rdev))
if err != nil {
return nil, fuse.ToStatus(err)
return nil, ToErrno(err)
}
st := syscall.Stat_t{}
if err := syscall.Lstat(p, &st); err != nil {
syscall.Rmdir(p)
return nil, fuse.ToStatus(err)
return nil, ToErrno(err)
}
out.Attr.FromStat(&st)
......@@ -91,19 +91,19 @@ func (n *loopbackNode) Mknod(ctx context.Context, name string, mode, rdev uint32
node := n.rootNode.newLoopbackNode()
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)
err := os.Mkdir(p, os.FileMode(mode))
if err != nil {
return nil, fuse.ToStatus(err)
return nil, ToErrno(err)
}
st := syscall.Stat_t{}
if err := syscall.Lstat(p, &st); err != nil {
syscall.Rmdir(p)
return nil, fuse.ToStatus(err)
return nil, ToErrno(err)
}
out.Attr.FromStat(&st)
......@@ -111,19 +111,19 @@ func (n *loopbackNode) Mkdir(ctx context.Context, name string, mode uint32, out
node := n.rootNode.newLoopbackNode()
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)
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)
err := syscall.Unlink(p)
return fuse.ToStatus(err)
return ToErrno(err)
}
func toLoopbackNode(op Operations) *loopbackNode {
......@@ -133,7 +133,7 @@ func toLoopbackNode(op Operations) *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)
if flags&unix.RENAME_EXCHANGE != 0 {
return n.renameExchange(name, newParentLoopback, newName)
......@@ -143,7 +143,7 @@ func (n *loopbackNode) Rename(ctx context.Context, name string, newParent Operat
p2 := filepath.Join(newParentLoopback.path(), newName)
err := os.Rename(p1, p2)
return fuse.ToStatus(err)
return ToErrno(err)
}
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)
fd, err := syscall.Open(p, int(flags)|os.O_CREATE, mode)
if err != nil {
return nil, nil, 0, fuse.ToStatus(err)
return nil, nil, 0, ToErrno(err)
}
st := syscall.Stat_t{}
if err := syscall.Fstat(fd, &st); err != nil {
syscall.Close(fd)
return nil, nil, 0, fuse.ToStatus(err)
return nil, nil, 0, ToErrno(err)
}
node := n.rootNode.newLoopbackNode()
ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st))
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)
err := syscall.Symlink(target, p)
if err != nil {
return nil, fuse.ToStatus(err)
return nil, ToErrno(err)
}
st := syscall.Stat_t{}
if syscall.Lstat(p, &st); err != nil {
syscall.Unlink(p)
return nil, fuse.ToStatus(err)
return nil, ToErrno(err)
}
node := n.rootNode.newLoopbackNode()
ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&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)
targetNode := toLoopbackNode(target)
err := syscall.Link(targetNode.path(), p)
if err != nil {
return nil, fuse.ToStatus(err)
return nil, ToErrno(err)
}
st := syscall.Stat_t{}
if syscall.Lstat(p, &st); err != nil {
syscall.Unlink(p)
return nil, fuse.ToStatus(err)
return nil, ToErrno(err)
}
node := n.rootNode.newLoopbackNode()
ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&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()
for l := 256; ; l *= 2 {
buf := make([]byte, l)
sz, err := syscall.Readlink(p, buf)
if err != nil {
return nil, fuse.ToStatus(err)
return nil, ToErrno(err)
}
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()
f, err := syscall.Open(p, int(flags), 0)
if err != nil {
return nil, 0, fuse.ToStatus(err)
return nil, 0, ToErrno(err)
}
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)
if err != nil {
return fuse.ToStatus(err)
return ToErrno(err)
}
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())
}
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 {
return f.GetAttr(ctx, out)
}
......@@ -273,28 +273,28 @@ func (n *loopbackNode) FGetAttr(ctx context.Context, f FileHandle, out *fuse.Att
st := syscall.Stat_t{}
err = syscall.Lstat(p, &st)
if err != nil {
return fuse.ToStatus(err)
return ToErrno(err)
}
out.FromStat(&st)
return fuse.OK
return OK
}
func (n *loopbackNode) CopyFileRange(ctx context.Context, fhIn FileHandle,
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)
if !ok {
return 0, fuse.ENOTSUP
return 0, syscall.ENOTSUP
}
lfOut, ok := fhOut.(*loopbackFile)
if !ok {
return 0, fuse.ENOTSUP
return 0, syscall.ENOTSUP
}
signedOffIn := int64(offIn)
signedOffOut := int64(offOut)
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
......
......@@ -8,55 +8,54 @@ import (
"context"
"syscall"
"github.com/hanwen/go-fuse/fuse"
"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)
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))
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)
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)
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)
if err != nil {
return fuse.ToStatus(err)
return ToErrno(err)
}
defer syscall.Close(fd1)
fd2, err := syscall.Open(newparent.path(), syscall.O_DIRECTORY, 0)
defer syscall.Close(fd2)
if err != nil {
return fuse.ToStatus(err)
return ToErrno(err)
}
var st syscall.Stat_t
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 {
return fuse.EBUSY
return syscall.EBUSY
}
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 {
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) {
t.Fatalf("got after %#v, want %#v", after, st)
}
if code := tc.loopback.Inode().NotifyEntry("file"); !code.Ok() {
t.Errorf("notify failed: %v", code)
if errno := tc.loopback.Inode().NotifyEntry("file"); errno != 0 {
t.Errorf("notify failed: %v", errno)
}
if err := syscall.Lstat(fn, &after); err != syscall.ENOENT {
......
......@@ -14,6 +14,7 @@ import (
"reflect"
"strings"
"sync"
"syscall"
"testing"
"github.com/hanwen/go-fuse/fuse"
......@@ -116,23 +117,23 @@ var _ = (FileOperations)((*zipFile)(nil))
// GetAttr sets the minimum, which is the size. A more full-featured
// 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
return fuse.OK
return OK
}
// 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()
defer zf.mu.Unlock()
if zf.data == nil {
rc, err := zf.file.Open()
if err != nil {
return nil, 0, fuse.EIO
return nil, 0, syscall.EIO
}
content, err := ioutil.ReadAll(rc)
if err != nil {
return nil, 0, fuse.EIO
return nil, 0, syscall.EIO
}
zf.data = content
......@@ -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
// one. The file content is immutable, so hint the kernel to
// 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
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)
if 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
......
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