mirror of
https://github.com/rclone/rclone.git
synced 2025-01-29 21:04:23 +02:00
fs/cache: fix moveto/copyto remote:file remote:file2
Before this change, if the cache was given a source `remote:file` it stored `remote:` with the error `fs.ErrorIsFile` attached. This meant that if it `remote:` was subsequently looked up it would return the `fs.ErrorIsFile` error. This broke `moveto remote:file remote:file2` as moveto would lookup `remote:` from the second argument and erroneously get the `fs.ErrorIsFile` error. This likely broke other commands too. This was broken in 4c9836035 fs/cache: Add Pin and Unpin and canonicalised lookup Which was released in v1.52.0 The fix is to make a new cache entry for `remote:` with no error attached in the case that the original call returned `fs.ErrorIsFile`.
This commit is contained in:
parent
50e36fb482
commit
8d5bc7f28b
18
fs/cache/cache.go
vendored
18
fs/cache/cache.go
vendored
@ -56,12 +56,20 @@ func GetFn(fsString string, create func(fsString string) (fs.Fs, error)) (f fs.F
|
|||||||
if created {
|
if created {
|
||||||
canonicalName := fs.ConfigString(f)
|
canonicalName := fs.ConfigString(f)
|
||||||
if canonicalName != fsString {
|
if canonicalName != fsString {
|
||||||
fs.Debugf(nil, "fs cache: renaming cache item %q to be canonical %q", fsString, canonicalName)
|
// Note that if err == fs.ErrorIsFile at this moment
|
||||||
value, found := c.Rename(fsString, canonicalName)
|
// then we can't rename the remote as it will have the
|
||||||
if found {
|
// wrong error status, we need to add a new one.
|
||||||
f = value.(fs.Fs)
|
if err == nil {
|
||||||
|
fs.Debugf(nil, "fs cache: renaming cache item %q to be canonical %q", fsString, canonicalName)
|
||||||
|
value, found := c.Rename(fsString, canonicalName)
|
||||||
|
if found {
|
||||||
|
f = value.(fs.Fs)
|
||||||
|
}
|
||||||
|
addMapping(fsString, canonicalName)
|
||||||
|
} else {
|
||||||
|
fs.Debugf(nil, "fs cache: adding new entry for parent of %q, %q", fsString, canonicalName)
|
||||||
|
Put(canonicalName, f)
|
||||||
}
|
}
|
||||||
addMapping(fsString, canonicalName)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return f, err
|
return f, err
|
||||||
|
37
fs/cache/cache_test.go
vendored
37
fs/cache/cache_test.go
vendored
@ -23,7 +23,7 @@ func mockNewFs(t *testing.T) (func(), func(path string) (fs.Fs, error)) {
|
|||||||
switch path {
|
switch path {
|
||||||
case "mock:/":
|
case "mock:/":
|
||||||
return mockfs.NewFs("mock", "/"), nil
|
return mockfs.NewFs("mock", "/"), nil
|
||||||
case "mock:/file.txt":
|
case "mock:/file.txt", "mock:file.txt":
|
||||||
return mockfs.NewFs("mock", "/"), fs.ErrorIsFile
|
return mockfs.NewFs("mock", "/"), fs.ErrorIsFile
|
||||||
case "mock:/error":
|
case "mock:/error":
|
||||||
return nil, errSentinel
|
return nil, errSentinel
|
||||||
@ -64,13 +64,46 @@ func TestGetFile(t *testing.T) {
|
|||||||
require.Equal(t, fs.ErrorIsFile, err)
|
require.Equal(t, fs.ErrorIsFile, err)
|
||||||
require.NotNil(t, f)
|
require.NotNil(t, f)
|
||||||
|
|
||||||
assert.Equal(t, 1, c.Entries())
|
assert.Equal(t, 2, c.Entries())
|
||||||
|
|
||||||
f2, err := GetFn("mock:/file.txt", create)
|
f2, err := GetFn("mock:/file.txt", create)
|
||||||
require.Equal(t, fs.ErrorIsFile, err)
|
require.Equal(t, fs.ErrorIsFile, err)
|
||||||
require.NotNil(t, f2)
|
require.NotNil(t, f2)
|
||||||
|
|
||||||
assert.Equal(t, f, f2)
|
assert.Equal(t, f, f2)
|
||||||
|
|
||||||
|
// check parent is there too
|
||||||
|
f2, err = GetFn("mock:/", create)
|
||||||
|
require.Nil(t, err)
|
||||||
|
require.NotNil(t, f2)
|
||||||
|
|
||||||
|
assert.Equal(t, f, f2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetFile2(t *testing.T) {
|
||||||
|
cleanup, create := mockNewFs(t)
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
|
assert.Equal(t, 0, c.Entries())
|
||||||
|
|
||||||
|
f, err := GetFn("mock:file.txt", create)
|
||||||
|
require.Equal(t, fs.ErrorIsFile, err)
|
||||||
|
require.NotNil(t, f)
|
||||||
|
|
||||||
|
assert.Equal(t, 2, c.Entries())
|
||||||
|
|
||||||
|
f2, err := GetFn("mock:file.txt", create)
|
||||||
|
require.Equal(t, fs.ErrorIsFile, err)
|
||||||
|
require.NotNil(t, f2)
|
||||||
|
|
||||||
|
assert.Equal(t, f, f2)
|
||||||
|
|
||||||
|
// check parent is there too
|
||||||
|
f2, err = GetFn("mock:/", create)
|
||||||
|
require.Nil(t, err)
|
||||||
|
require.NotNil(t, f2)
|
||||||
|
|
||||||
|
assert.Equal(t, f, f2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetError(t *testing.T) {
|
func TestGetError(t *testing.T) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user