1
mirror of https://github.com/rclone/rclone synced 2024-12-22 13:03:02 +01:00

vfs: Don't error a r/w file open without cache; delay error until Read called

If we open a file for r/w without the cache we now always return a
handle and return an error if the file is ever read from.  This fixes
incompatibility with cmount under windows.
This commit is contained in:
Nick Craig-Wood 2017-11-16 10:55:24 +00:00
parent dec21ccf63
commit 992647b157
4 changed files with 30 additions and 5 deletions

View File

@ -382,11 +382,11 @@ func (f *File) Open(flags int) (fd Handle, err error) {
if read && write {
if CacheMode >= CacheModeMinimal {
fd, err = f.OpenRW(flags)
} else if flags&os.O_TRUNC != 0 {
fd, err = f.OpenWrite()
} else {
fs.Errorf(f, "Can't open for read and write without cache")
return nil, EPERM
// Open write only and hope the user doesn't
// want to read. If they do they will get an
// EPERM plus an Error log.
fd, err = f.OpenWrite()
}
} else if write {
if CacheMode >= CacheModeWrites {

View File

@ -172,7 +172,9 @@ func TestFileOpen(t *testing.T) {
require.NoError(t, fd.Close())
fd, err = file.Open(os.O_RDWR)
assert.Equal(t, EPERM, err)
assert.NoError(t, err)
_, ok = fd.(*WriteFileHandle)
assert.True(t, ok)
fd, err = file.Open(3)
assert.Equal(t, EPERM, err)

View File

@ -248,3 +248,17 @@ func (fh *WriteFileHandle) Truncate(size int64) (err error) {
// File is correct size
return nil
}
// Read reads up to len(p) bytes into p.
func (fh *WriteFileHandle) Read(p []byte) (n int, err error) {
fs.Errorf(fh.remote, "Read: Can't read and write to file without cache")
return 0, EPERM
}
// ReadAt reads len(p) bytes into p starting at offset off in the
// underlying input source. It returns the number of bytes read (0 <=
// n <= len(p)) and any error encountered.
func (fh *WriteFileHandle) ReadAt(p []byte, off int64) (n int, err error) {
fs.Errorf(fh.remote, "ReadAt: Can't read and write to file without cache")
return 0, EPERM
}

View File

@ -56,6 +56,15 @@ func TestWriteFileHandleMethods(t *testing.T) {
assert.Equal(t, int64(5), fi.Size())
assert.Equal(t, "file1", fi.Name())
// Read
var buf = make([]byte, 16)
_, err = fh.Read(buf)
assert.Equal(t, EPERM, err)
// ReadAt
_, err = fh.ReadAt(buf, 0)
assert.Equal(t, EPERM, err)
// Close
assert.NoError(t, fh.Close())