mirror of
https://github.com/rclone/rclone.git
synced 2026-07-13 01:02:15 -04:00
filen: fix incorrect in-memory modtime after upload
Put and Update were returning Objects whose in-memory modtime was the nanosecond-precision source modtime, while the server stores millisecond precision. After the upload returned, the in-memory state did not match what a fresh List would report, which broke wrappers that compare modtimes (e.g. the hasher backend's fingerprint). The standard for backends is to re-read metadata after Upload so this re-reads the file via FindFile after the upload completes so the Object reflects the server's authoritative state. The chunked upload path already re-reads via NewObject in multiThreadCopy, so this only needs to apply to Put and Update. Fixes #9308
This commit is contained in:
@@ -339,7 +339,10 @@ func (f *Fs) Put(ctx context.Context, in io.Reader, src fs.ObjectInfo, options .
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uploadedFile, err := f.filen.UploadFile(ctx, incompleteFile, in)
|
||||
if _, err := f.filen.UploadFile(ctx, incompleteFile, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uploadedFile, err := f.readMetadata(ctx, resolvedPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -350,6 +353,22 @@ func (f *Fs) Put(ctx context.Context, in io.Reader, src fs.ObjectInfo, options .
|
||||
}, nil
|
||||
}
|
||||
|
||||
// readMetadata re-reads the file's metadata from the server after an
|
||||
// upload so the in-memory state reflects what is actually stored
|
||||
// (e.g. modtime at the server's precision). Without this, callers
|
||||
// would see higher-precision modtimes locally than List would return,
|
||||
// breaking layers like the hasher backend that fingerprint by modtime.
|
||||
func (f *Fs) readMetadata(ctx context.Context, resolvedPath string) (*types.File, error) {
|
||||
file, err := f.filen.FindFile(ctx, resolvedPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if file == nil {
|
||||
return nil, fs.ErrorObjectNotFound
|
||||
}
|
||||
return file, nil
|
||||
}
|
||||
|
||||
// PutStream uploads to the remote path with the modTime given of indeterminate size
|
||||
//
|
||||
// May create the object even if it returns an error - if so
|
||||
@@ -760,7 +779,10 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op
|
||||
newIncomplete.LastModified = newModTime
|
||||
newIncomplete.Created = newModTime
|
||||
newIncomplete.SetMimeType(fs.MimeType(ctx, src))
|
||||
uploadedFile, err := o.fs.filen.UploadFile(ctx, newIncomplete, in)
|
||||
if _, err := o.fs.filen.UploadFile(ctx, newIncomplete, in); err != nil {
|
||||
return err
|
||||
}
|
||||
uploadedFile, err := o.fs.readMetadata(ctx, o.fs.resolvePath(o.path))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user