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
This commit is contained in:
Nick Craig-Wood
2022-09-12 13:25:15 +01:00
parent 404059fd95
commit 4488bc0cd7

View File

@@ -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
} }