From 71e98ea584def6769a14037fdb9aec3e535078cf Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Mon, 7 Jan 2019 14:49:27 +0000 Subject: [PATCH] vfs: fix renaming/deleting open files with cache mode "writes" under Windows Before this change, renaming and deleting of open files (which can easily happen due to the asynchronous nature of file systems) would produce an error, for example saving files with Firefox. After this change we open files with the flags necessary for open files to be renamed or deleted. Fixes #2730 --- vfs/make_open_tests.go | 10 ++++++---- vfs/read_write.go | 5 +++-- vfs/test_vfs/test_vfs.go | 4 +++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/vfs/make_open_tests.go b/vfs/make_open_tests.go index 785bbc986..f0c4dd661 100644 --- a/vfs/make_open_tests.go +++ b/vfs/make_open_tests.go @@ -15,6 +15,8 @@ import ( "log" "os" "strings" + + "github.com/ncw/rclone/lib/file" ) // Interprets err into a vfs error @@ -45,7 +47,7 @@ func test(fileName string, flags int, mode string) { if !os.IsNotExist(err) { log.Fatalf("File must not exist") } - f, openNonExistentErr := os.OpenFile(fileName, flags, 0666) + f, openNonExistentErr := file.OpenFile(fileName, flags, 0666) var readNonExistentErr error var writeNonExistentErr error @@ -65,7 +67,7 @@ func test(fileName string, flags int, mode string) { } // write the file - f, err = os.Create(fileName) + f, err = file.Create(fileName) if err != nil { log.Fatalf("failed to create: %v", err) } @@ -81,7 +83,7 @@ func test(fileName string, flags int, mode string) { // then open file and try with file existing - f, openExistingErr := os.OpenFile(fileName, flags, 0666) + f, openExistingErr := file.OpenFile(fileName, flags, 0666) var readExistingErr error var writeExistingErr error if openExistingErr == nil { @@ -100,7 +102,7 @@ func test(fileName string, flags int, mode string) { } // read the file - f, err = os.Open(fileName) + f, err = file.Open(fileName) if err != nil { log.Fatalf("failed to open: %v", err) } diff --git a/vfs/read_write.go b/vfs/read_write.go index 2659c57b2..3cd436659 100644 --- a/vfs/read_write.go +++ b/vfs/read_write.go @@ -12,6 +12,7 @@ import ( "github.com/ncw/rclone/fs/accounting" "github.com/ncw/rclone/fs/log" "github.com/ncw/rclone/fs/operations" + "github.com/ncw/rclone/lib/file" "github.com/pkg/errors" ) @@ -124,7 +125,7 @@ func (fh *RWFileHandle) openPending(truncate bool) (err error) { } // try to open a exising cache file - fd, err = os.OpenFile(fh.osPath, cacheFileOpenFlags&^os.O_CREATE, 0600) + fd, err = file.OpenFile(fh.osPath, cacheFileOpenFlags&^os.O_CREATE, 0600) if os.IsNotExist(err) { // cache file does not exist, so need to fetch it if we have an object to fetch // it from @@ -185,7 +186,7 @@ func (fh *RWFileHandle) openPending(truncate bool) (err error) { if fd == nil { fs.Debugf(fh.logPrefix(), "Opening cached copy with flags=%s", decodeOpenFlags(fh.flags)) - fd, err = os.OpenFile(fh.osPath, cacheFileOpenFlags, 0600) + fd, err = file.OpenFile(fh.osPath, cacheFileOpenFlags, 0600) if err != nil { return errors.Wrap(err, "cache open file failed") } diff --git a/vfs/test_vfs/test_vfs.go b/vfs/test_vfs/test_vfs.go index cfb3a24bc..1da64f16e 100644 --- a/vfs/test_vfs/test_vfs.go +++ b/vfs/test_vfs/test_vfs.go @@ -16,6 +16,8 @@ import ( "sync" "sync/atomic" "time" + + "github.com/ncw/rclone/lib/file" ) var ( @@ -194,7 +196,7 @@ func (t *Test) close() { func (t *Test) open() { t.close() t.logf("open") - handle, err := os.OpenFile(t.path(), os.O_RDWR|os.O_CREATE, 0666) + handle, err := file.OpenFile(t.path(), os.O_RDWR|os.O_CREATE, 0666) if err != nil { t.errorf("failed to open: %v", err) return