diff --git a/cmd/cmount/fs.go b/cmd/cmount/fs.go index 5696c2a33..bcbf76b4f 100644 --- a/cmd/cmount/fs.go +++ b/cmd/cmount/fs.go @@ -515,10 +515,14 @@ func translateError(err error) (errc int) { return 0 case vfs.ENOENT: return -fuse.ENOENT - case vfs.ENOTEMPTY: - return -fuse.ENOTEMPTY case vfs.EEXIST: return -fuse.EEXIST + case vfs.EPERM: + return -fuse.EPERM + case vfs.ECLOSED: + return -fuse.EBADF + case vfs.ENOTEMPTY: + return -fuse.ENOTEMPTY case vfs.ESPIPE: return -fuse.ESPIPE case vfs.EBADF: @@ -527,8 +531,6 @@ func translateError(err error) (errc int) { return -fuse.EROFS case vfs.ENOSYS: return -fuse.ENOSYS - case vfs.EPERM: - return -fuse.EPERM } fs.Errorf(nil, "IO error: %v", err) return -fuse.EIO diff --git a/cmd/mount/fs.go b/cmd/mount/fs.go index 157e9f09a..bf4a5bc5e 100644 --- a/cmd/mount/fs.go +++ b/cmd/mount/fs.go @@ -74,10 +74,14 @@ func translateError(err error) error { return nil case vfs.ENOENT: return fuse.ENOENT - case vfs.ENOTEMPTY: - return fuse.Errno(syscall.ENOTEMPTY) case vfs.EEXIST: return fuse.EEXIST + case vfs.EPERM: + return fuse.EPERM + case vfs.ECLOSED: + return fuse.Errno(syscall.EBADF) + case vfs.ENOTEMPTY: + return fuse.Errno(syscall.ENOTEMPTY) case vfs.ESPIPE: return fuse.Errno(syscall.ESPIPE) case vfs.EBADF: @@ -86,8 +90,6 @@ func translateError(err error) error { return fuse.Errno(syscall.EROFS) case vfs.ENOSYS: return fuse.ENOSYS - case vfs.EPERM: - return fuse.EPERM } return err } diff --git a/vfs/errors.go b/vfs/errors.go index 28e768682..ac00ca9ad 100644 --- a/vfs/errors.go +++ b/vfs/errors.go @@ -7,7 +7,7 @@ import ( "os" ) -// Error describes low level errors in a cross platform way +// Error describes low level errors in a cross platform way. type Error byte // NB if changing errors translateError in cmd/mount/fs.go, cmd/cmount/fs.go @@ -27,6 +27,7 @@ var ( ENOENT = os.ErrNotExist EEXIST = os.ErrExist EPERM = os.ErrPermission + // ECLOSED see errors_{old,new}.go ) var errorNames = []string{ diff --git a/vfs/errors_new.go b/vfs/errors_new.go new file mode 100644 index 000000000..66e2671ff --- /dev/null +++ b/vfs/errors_new.go @@ -0,0 +1,10 @@ +// Errors for go1.8+ + +//+build go1.8 + +package vfs + +import "os" + +// ECLOSED is returned when a handle is closed twice +var ECLOSED = os.ErrClosed diff --git a/vfs/errors_old.go b/vfs/errors_old.go new file mode 100644 index 000000000..b098a8b80 --- /dev/null +++ b/vfs/errors_old.go @@ -0,0 +1,10 @@ +// Errors for pre go1.8 + +//+build !go1.8 + +package vfs + +import "errors" + +// ECLOSED is returned when a handle is closed twice +var ECLOSED = errors.New("file already closed") diff --git a/vfs/read.go b/vfs/read.go index 0b14f1ab3..8b505999f 100644 --- a/vfs/read.go +++ b/vfs/read.go @@ -175,7 +175,7 @@ func (fh *ReadFileHandle) ReadAt(p []byte, off int64) (n int, err error) { // fs.Debugf(fh.o, "ReadFileHandle.Read size %d offset %d", reqSize, off) if fh.closed { fs.Errorf(fh.o, "ReadFileHandle.Read error: %v", EBADF) - return 0, EBADF + return 0, ECLOSED } doSeek := off != fh.offset if doSeek && fh.noSeek { @@ -305,7 +305,7 @@ func (fh *ReadFileHandle) Read(p []byte) (n int, err error) { // Must be called with fh.mu held func (fh *ReadFileHandle) close() error { if fh.closed { - return EBADF + return ECLOSED } fh.closed = true diff --git a/vfs/read_test.go b/vfs/read_test.go index 76613dfe4..23a2bfd52 100644 --- a/vfs/read_test.go +++ b/vfs/read_test.go @@ -76,7 +76,7 @@ func TestReadFileHandleMethods(t *testing.T) { assert.True(t, fh.closed) // Close again - assert.Equal(t, EBADF, fh.Close()) + assert.Equal(t, ECLOSED, fh.Close()) } func TestReadFileHandleSeek(t *testing.T) { @@ -177,7 +177,7 @@ func TestReadFileHandleReadAt(t *testing.T) { // check reading on closed file fh.noSeek = true n, err = fh.ReadAt(buf, 100) - assert.Equal(t, EBADF, err) + assert.Equal(t, ECLOSED, err) } func TestReadFileHandleFlush(t *testing.T) { diff --git a/vfs/vfs.go b/vfs/vfs.go index 6f57aeb54..31703bf99 100644 --- a/vfs/vfs.go +++ b/vfs/vfs.go @@ -11,6 +11,11 @@ // use paths with slashes in. // // It also includes directory caching +// +// The vfs package returns Error values to signal precisely which +// error conditions have ocurred. It may also return general errors +// it receives. It tries to use os Error values (eg os.ErrExist) +// where possible. package vfs import ( diff --git a/vfs/write.go b/vfs/write.go index 0d82fa5ce..7573aa142 100644 --- a/vfs/write.go +++ b/vfs/write.go @@ -88,7 +88,7 @@ func (fh *WriteFileHandle) WriteAt(p []byte, off int64) (n int, err error) { defer fh.mu.Unlock() if fh.closed { fs.Errorf(fh.remote, "WriteFileHandle.Write error: %v", EBADF) - return 0, EBADF + return 0, ECLOSED } if fh.offset != off { fs.Errorf(fh.remote, "WriteFileHandle.Write can't seek in file") @@ -129,7 +129,7 @@ func (fh *WriteFileHandle) Offset() (offset int64) { // Must be called with fh.mu held func (fh *WriteFileHandle) close() error { if fh.closed { - return EBADF + return ECLOSED } fh.closed = true fh.file.addWriters(-1) diff --git a/vfs/write_test.go b/vfs/write_test.go index fd494d1eb..56baa1251 100644 --- a/vfs/write_test.go +++ b/vfs/write_test.go @@ -61,7 +61,7 @@ func TestWriteFileHandleMethods(t *testing.T) { // Check double close err = fh.Close() - assert.Equal(t, EBADF, err) + assert.Equal(t, ECLOSED, err) // check vfs root, err := vfs.Root() @@ -105,7 +105,7 @@ func TestWriteFileHandleWriteAt(t *testing.T) { // Check can't write on closed handle n, err = fh.WriteAt([]byte("hello"), 0) - assert.Equal(t, EBADF, err) + assert.Equal(t, ECLOSED, err) assert.Equal(t, 0, n) // check vfs