combine: fix operations.DirMove across upstreams - fixes #7661
Before this change, operations.DirMove would fail when moving a directory, if the src and dest were on different upstreams of a combine remote. The issue only affected operations.DirMove, and not sync.MoveDir, because they checked for server-side-move support in different ways. MoveDir checks by just trying it and seeing what error comes back. This works fine for combine because combine returns fs.ErrorCantDirMove which MoveDir understands what to do with. DirMove, however, only checked whether the function pointer is nil. This is an unreliable way to check for combine, because combine does advertise support for DirMove, despite not always being able to do it. This change fixes the issue by checking the returned error in a manner similar to sync.MoveDir and falling back to individual file moves (copy + delete) depending on which error was returned.
This commit is contained in:
parent
252562d00a
commit
431524445e
2 changed files with 31 additions and 1 deletions
|
@ -2310,7 +2310,10 @@ func DirMove(ctx context.Context, f fs.Fs, srcRemote, dstRemote string) (err err
|
||||||
if err == nil {
|
if err == nil {
|
||||||
accounting.Stats(ctx).Renames(1)
|
accounting.Stats(ctx).Renames(1)
|
||||||
}
|
}
|
||||||
return err
|
if err != fs.ErrorCantDirMove && err != fs.ErrorDirExists {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fs.Infof(f, "Can't DirMove - falling back to file moves: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the directory tree into memory
|
// Load the directory tree into memory
|
||||||
|
|
|
@ -1405,6 +1405,33 @@ func TestDirMove(t *testing.T) {
|
||||||
fs.GetModifyWindow(ctx, r.Fremote),
|
fs.GetModifyWindow(ctx, r.Fremote),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Try with a DirMove method that exists but returns fs.ErrorCantDirMove (ex. combine moving across upstreams)
|
||||||
|
// Should fall back to manual move (copy + delete)
|
||||||
|
|
||||||
|
features.DirMove = func(ctx context.Context, src fs.Fs, srcRemote string, dstRemote string) error {
|
||||||
|
return fs.ErrorCantDirMove
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NoError(t, operations.DirMove(ctx, r.Fremote, "A3", "A4"))
|
||||||
|
|
||||||
|
for i := range files {
|
||||||
|
files[i].Path = strings.ReplaceAll(files[i].Path, "A3/", "A4/")
|
||||||
|
}
|
||||||
|
|
||||||
|
fstest.CheckListingWithPrecision(
|
||||||
|
t,
|
||||||
|
r.Fremote,
|
||||||
|
files,
|
||||||
|
[]string{
|
||||||
|
"A4",
|
||||||
|
"A4/B1",
|
||||||
|
"A4/B2",
|
||||||
|
"A4/B1/C1",
|
||||||
|
"A4/B1/C2",
|
||||||
|
"A4/B1/C3",
|
||||||
|
},
|
||||||
|
fs.GetModifyWindow(ctx, r.Fremote),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetFsInfo(t *testing.T) {
|
func TestGetFsInfo(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue