1
0
mirror of https://github.com/rclone/rclone.git synced 2025-12-15 15:53:41 +00:00

vfs: don't cache the object in read and read/write handles

This should help with inconsistent reads when the source object changes.
This commit is contained in:
Nick Craig-Wood
2018-03-01 15:50:23 +00:00
parent ebfeec9fb4
commit 7fb53a031c
3 changed files with 49 additions and 38 deletions

View File

@@ -22,8 +22,7 @@ import (
type RWFileHandle struct {
*os.File
mu sync.Mutex
closed bool // set if handle has been closed
o fs.Object // may be nil
closed bool // set if handle has been closed
remote string
file *File
d *Dir
@@ -51,7 +50,6 @@ func newRWFileHandle(d *Dir, f *File, remote string, flags int) (fh *RWFileHandl
}
fh = &RWFileHandle{
o: f.o,
file: f,
d: d,
remote: remote,
@@ -107,16 +105,18 @@ func (fh *RWFileHandle) openPending(truncate bool) (err error) {
fh.file.muOpen.Lock()
defer fh.file.muOpen.Unlock()
o := fh.file.getObject()
var fd *os.File
cacheFileOpenFlags := fh.flags
// if not truncating the file, need to read it first
if fh.flags&os.O_TRUNC == 0 && !truncate {
// If the remote object exists AND its cached file exists locally AND there are no
// other handles with it open writers, then attempt to update it.
if fh.o != nil && fh.d.vfs.cache.opens(fh.remote) <= 1 {
if o != nil && fh.d.vfs.cache.opens(fh.remote) <= 1 {
cacheObj, err := fh.d.vfs.cache.f.NewObject(fh.remote)
if err == nil && cacheObj != nil {
cacheObj, err = copyObj(fh.d.vfs.cache.f, cacheObj, fh.remote, fh.o)
cacheObj, err = copyObj(fh.d.vfs.cache.f, cacheObj, fh.remote, o)
if err != nil {
return errors.Wrap(err, "open RW handle failed to update cached file")
}
@@ -128,8 +128,8 @@ func (fh *RWFileHandle) openPending(truncate bool) (err error) {
if os.IsNotExist(err) {
// cache file does not exist, so need to fetch it if we have an object to fetch
// it from
if fh.o != nil {
_, err = copyObj(fh.d.vfs.cache.f, nil, fh.remote, fh.o)
if o != nil {
_, err = copyObj(fh.d.vfs.cache.f, nil, fh.remote, o)
if err != nil {
cause := errors.Cause(err)
if cause != fs.ErrorObjectNotFound && cause != fs.ErrorDirNotFound {
@@ -296,7 +296,7 @@ func (fh *RWFileHandle) close() (err error) {
return err
}
o, err := copyObj(fh.d.vfs.f, fh.o, fh.remote, cacheObj)
o, err := copyObj(fh.d.vfs.f, fh.file.getObject(), fh.remote, cacheObj)
if err != nil {
err = errors.Wrap(err, "failed to transfer file from cache to remote")
fs.Errorf(fh.logPrefix(), "%v", err)