vfs: Fix IO Error opening a file with O_CREATE|O_RDONLY in --vfs-cache-mode not full

Before this fix, opening a file with `O_CREATE|O_RDONLY` caused an IO error to
be returned when using `--vfs-cache-mode off` or `--vfs-cache-mode writes`.

This was because the file was opened with read intent, but the `O_CREATE`
implies write intent to create the file even though the file is opened
`O_RDONLY`.

This fix sets write intent for the file if `O_CREATE` is passed in which fixes
the problem for all the VFS cache modes.

It also extends the exhaustive open flags testing to `--vfs-cache-mode writes`
as well as `--vfs-cache-mode full` which would have caught this problem.

See: https://forum.rclone.org/t/i-o-error-trashing-file-on-sftp-mount/34317/
This commit is contained in:
Nick Craig-Wood 2022-11-24 10:30:01 +00:00
parent 0edf6478e3
commit 46b080c092
2 changed files with 17 additions and 8 deletions

View File

@ -698,6 +698,11 @@ func (f *File) Open(flags int) (fd Handle, err error) {
write = true
}
// If create is set then set write to force openRW
if flags&os.O_CREATE != 0 {
write = true
}
// Open the correct sort of handle
f.mu.RLock()
d := f.d

View File

@ -642,15 +642,19 @@ func testRWFileHandleOpenTest(t *testing.T, vfs *VFS, test *openTest) {
}
func TestRWFileHandleOpenTests(t *testing.T) {
opt := vfscommon.DefaultOpt
opt.CacheMode = vfscommon.CacheModeFull
opt.WriteBack = writeBackDelay
_, vfs, cleanup := newTestVFSOpt(t, &opt)
defer cleanup()
for _, cacheMode := range []vfscommon.CacheMode{vfscommon.CacheModeWrites, vfscommon.CacheModeFull} {
t.Run(cacheMode.String(), func(t *testing.T) {
opt := vfscommon.DefaultOpt
opt.CacheMode = cacheMode
opt.WriteBack = writeBackDelay
_, vfs, cleanup := newTestVFSOpt(t, &opt)
defer cleanup()
for _, test := range openTests {
t.Run(test.what, func(t *testing.T) {
testRWFileHandleOpenTest(t, vfs, &test)
for _, test := range openTests {
t.Run(test.what, func(t *testing.T) {
testRWFileHandleOpenTest(t, vfs, &test)
})
}
})
}
}