mirror of
https://github.com/rclone/rclone.git
synced 2024-11-22 08:23:47 +01:00
vfs: fix open file renaming on drive when using --vfs-cache-mode writes
Before this change, when uploading files from the VFS cache which were pending a rename, rclone would use the new path of the object when specifiying the destination remote. This didn't cause a problem with most backends as the subsequent rename did nothing, however with the drive backend, since it updates objects, the incorrect Remote was embedded in the object. This caused the rename to apparently succeed but the object be at the wrong location. The fix for this was to make sure we upload to the path stored in the object if available. This problem was spotted by the new rename tests for the VFS layer.
This commit is contained in:
parent
5f822f2660
commit
63128834da
17
vfs/file.go
17
vfs/file.go
@ -150,13 +150,6 @@ func (f *File) rename(ctx context.Context, destDir *Dir, newName string) error {
|
||||
newPath := path.Join(destDir.path, newName)
|
||||
|
||||
renameCall := func(ctx context.Context) error {
|
||||
f.mu.RLock()
|
||||
o := f.o
|
||||
f.mu.RUnlock()
|
||||
if o == nil {
|
||||
return errors.New("Cannot rename: file object is not available")
|
||||
}
|
||||
|
||||
// chain rename calls if any
|
||||
if oldPendingRenameFun != nil {
|
||||
err := oldPendingRenameFun(ctx)
|
||||
@ -165,6 +158,16 @@ func (f *File) rename(ctx context.Context, destDir *Dir, newName string) error {
|
||||
}
|
||||
}
|
||||
|
||||
f.mu.RLock()
|
||||
o := f.o
|
||||
f.mu.RUnlock()
|
||||
if o == nil {
|
||||
return errors.New("Cannot rename: file object is not available")
|
||||
}
|
||||
if o.Remote() == newPath {
|
||||
return nil // no need to rename
|
||||
}
|
||||
|
||||
// do the move of the remote object
|
||||
dstOverwritten, _ := d.f.NewObject(ctx, newPath)
|
||||
newObject, err := operations.Move(ctx, d.f, dstOverwritten, newPath, o)
|
||||
|
@ -284,7 +284,12 @@ func (fh *RWFileHandle) flushWrites(closeFile bool) error {
|
||||
return err
|
||||
}
|
||||
|
||||
o, err := copyObj(fh.d.vfs.f, fh.file.getObject(), fh.file.Path(), cacheObj)
|
||||
objPath := fh.file.Path()
|
||||
objOld := fh.file.getObject()
|
||||
if objOld != nil {
|
||||
objPath = objOld.Remote() // use the path of the actual object if available
|
||||
}
|
||||
o, err := copyObj(fh.d.vfs.f, objOld, objPath, cacheObj)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "failed to transfer file from cache to remote")
|
||||
fs.Errorf(fh.logPrefix(), "%v", err)
|
||||
|
Loading…
Reference in New Issue
Block a user