operations: allow --server-side-across-configs to work between any backends

Before this change --server-side-across-configs would only work
between two backends of the same type.

This meant that server side copies from a backend to a union of that
backend didn't work where they really should have done.

Fixes #6287
This commit is contained in:
Nick Craig-Wood 2022-09-06 12:53:02 +01:00
parent be53dcc9c9
commit 404059fd95

View file

@ -383,6 +383,20 @@ func CommonHash(ctx context.Context, fa, fb fs.Info) (hash.Type, *fs.HashesOptio
return hashType, &fs.HashesOption{Hashes: common} return hashType, &fs.HashesOption{Hashes: common}
} }
// Is it OK to server side move/copy from src to dst
func serverSideOK(ci *fs.ConfigInfo, fDst, fSrc fs.Info) bool {
if ci.ServerSideAcrossConfigs {
return true
}
if SameConfig(fSrc, fDst) {
return true
}
if SameRemoteType(fSrc, fDst) {
return fDst.Features().ServerSideAcrossConfigs
}
return false
}
// Copy src object to dst or f if nil. If dst is nil then it uses // Copy src object to dst or f if nil. If dst is nil then it uses
// remote as the name of the new object. // remote as the name of the new object.
// //
@ -424,7 +438,7 @@ func Copy(ctx context.Context, f fs.Fs, dst fs.Object, remote string, src fs.Obj
return nil, accounting.ErrorMaxTransferLimitReachedGraceful return nil, accounting.ErrorMaxTransferLimitReachedGraceful
} }
} }
if doCopy := f.Features().Copy; doCopy != nil && (SameConfig(src.Fs(), f) || (SameRemoteType(src.Fs(), f) && (f.Features().ServerSideAcrossConfigs || ci.ServerSideAcrossConfigs))) { if doCopy := f.Features().Copy; doCopy != nil && serverSideOK(ci, f, src.Fs()) {
in := tr.Account(ctx, nil) // account the transfer in := tr.Account(ctx, nil) // account the transfer
in.ServerSideCopyStart() in.ServerSideCopyStart()
newDst, err = doCopy(ctx, src, remote) newDst, err = doCopy(ctx, src, remote)
@ -619,7 +633,7 @@ func Move(ctx context.Context, fdst fs.Fs, dst fs.Object, remote string, src fs.
return newDst, nil return newDst, nil
} }
// See if we have Move available // See if we have Move available
if doMove := fdst.Features().Move; doMove != nil && (SameConfig(src.Fs(), fdst) || (SameRemoteType(src.Fs(), fdst) && (fdst.Features().ServerSideAcrossConfigs || ci.ServerSideAcrossConfigs))) { if doMove := fdst.Features().Move; doMove != nil && serverSideOK(ci, fdst, src.Fs()) {
// Delete destination if it exists and is not the same file as src (could be same file while seemingly different if the remote is case insensitive) // Delete destination if it exists and is not the same file as src (could be same file while seemingly different if the remote is case insensitive)
if dst != nil && !SameObject(src, dst) { if dst != nil && !SameObject(src, dst) {
err = DeleteFile(ctx, dst) err = DeleteFile(ctx, dst)