From 4488bc0cd7be4085039a6b73dbcf46352a6bb31f Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Mon, 12 Sep 2022 13:25:15 +0100 Subject: [PATCH] union: make server side copies possible from outside the union Before this change, only server side copies within the union would be permitted. This change allows server side copies from outside the union to happen, delegating the checking to the individual upstream backend. The same change should be made to Move and DirMove Fixes #6287 --- backend/union/union.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/backend/union/union.go b/backend/union/union.go index 7e10f06b8..412900d51 100644 --- a/backend/union/union.go +++ b/backend/union/union.go @@ -222,19 +222,19 @@ func (f *Fs) Purge(ctx context.Context, dir string) error { // // If it isn't possible then return fs.ErrorCantCopy func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, error) { - srcObj, ok := src.(*Object) - if !ok { - fs.Debugf(src, "Can't copy - not same remote type") - return nil, fs.ErrorCantCopy - } - o := srcObj.UnWrapUpstream() - su := o.UpstreamFs() - if su.Features().Copy == nil { - return nil, fs.ErrorCantCopy + var srcFs fs.Info + if srcObj, ok := src.(*Object); ok { + // Have a union object - unwrap + o := srcObj.UnWrapUpstream() + srcFs = o.UpstreamFs() + src = o + } else { + // Have a non union object - it might be compatible with a union member + srcFs = src.Fs() } var du *upstream.Fs for _, u := range f.upstreams { - if operations.Same(u.RootFs, su.RootFs) { + if u.Features().Copy != nil && operations.Same(u.RootFs, srcFs) { du = u } } @@ -244,7 +244,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, if !du.IsCreatable() { 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 { return nil, err }