Compare commits
2 commits
tcl/master
...
fix-6287-s
Author | SHA1 | Date | |
---|---|---|---|
|
4488bc0cd7 | ||
|
404059fd95 |
2 changed files with 27 additions and 13 deletions
|
@ -222,19 +222,19 @@ func (f *Fs) Purge(ctx context.Context, dir string) error {
|
||||||
//
|
//
|
||||||
// If it isn't possible then return fs.ErrorCantCopy
|
// If it isn't possible then return fs.ErrorCantCopy
|
||||||
func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, error) {
|
func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, error) {
|
||||||
srcObj, ok := src.(*Object)
|
var srcFs fs.Info
|
||||||
if !ok {
|
if srcObj, ok := src.(*Object); ok {
|
||||||
fs.Debugf(src, "Can't copy - not same remote type")
|
// Have a union object - unwrap
|
||||||
return nil, fs.ErrorCantCopy
|
o := srcObj.UnWrapUpstream()
|
||||||
}
|
srcFs = o.UpstreamFs()
|
||||||
o := srcObj.UnWrapUpstream()
|
src = o
|
||||||
su := o.UpstreamFs()
|
} else {
|
||||||
if su.Features().Copy == nil {
|
// Have a non union object - it might be compatible with a union member
|
||||||
return nil, fs.ErrorCantCopy
|
srcFs = src.Fs()
|
||||||
}
|
}
|
||||||
var du *upstream.Fs
|
var du *upstream.Fs
|
||||||
for _, u := range f.upstreams {
|
for _, u := range f.upstreams {
|
||||||
if operations.Same(u.RootFs, su.RootFs) {
|
if u.Features().Copy != nil && operations.Same(u.RootFs, srcFs) {
|
||||||
du = u
|
du = u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,7 +244,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object,
|
||||||
if !du.IsCreatable() {
|
if !du.IsCreatable() {
|
||||||
return nil, fs.ErrorPermissionDenied
|
return nil, fs.ErrorPermissionDenied
|
||||||
}
|
}
|
||||||
co, err := du.Features().Copy(ctx, o, remote)
|
co, err := du.Features().Copy(ctx, src, remote)
|
||||||
if err != nil || co == nil {
|
if err != nil || co == nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Reference in a new issue