mirror of
https://github.com/rclone/rclone.git
synced 2024-11-22 15:30:06 +08:00
vfs: stop empty dirs disappearing when renamed on bucket based remotes
Before this change when we renamed a directory this cleared the directory cache for the parent directory too. If the directory was remaining in the same parent this wasn't necessary and caused the empty directory to fall out of the cache. Fixes #3597
This commit is contained in:
parent
b63e9befe8
commit
1fe1a19339
27
vfs/dir.go
27
vfs/dir.go
|
@ -96,10 +96,27 @@ func (d *Dir) Node() Node {
|
|||
return d
|
||||
}
|
||||
|
||||
// forgetDirPath clears the cache for itself and all subdirectories if
|
||||
// they match the given path. The path is specified relative from the
|
||||
// directory it is called from.
|
||||
//
|
||||
// It does not invalidate or clear the cache of the parent directory.
|
||||
func (d *Dir) forgetDirPath(relativePath string) {
|
||||
if dir := d.cachedDir(relativePath); dir != nil {
|
||||
dir.walk(func(dir *Dir) {
|
||||
fs.Debugf(dir.path, "forgetting directory cache")
|
||||
dir.read = time.Time{}
|
||||
dir.items = make(map[string]Node)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ForgetAll ensures the directory and all its children are purged
|
||||
// from the cache.
|
||||
//
|
||||
// It does not invalidate or clear the cache of the parent directory.
|
||||
func (d *Dir) ForgetAll() {
|
||||
d.ForgetPath("", fs.EntryDirectory)
|
||||
d.forgetDirPath("")
|
||||
}
|
||||
|
||||
// ForgetPath clears the cache for itself and all subdirectories if
|
||||
|
@ -126,13 +143,7 @@ func (d *Dir) ForgetPath(relativePath string, entryType fs.EntryType) {
|
|||
}
|
||||
|
||||
if entryType == fs.EntryDirectory {
|
||||
if dir := d.cachedDir(relativePath); dir != nil {
|
||||
dir.walk(func(dir *Dir) {
|
||||
fs.Debugf(dir.path, "forgetting directory cache")
|
||||
dir.read = time.Time{}
|
||||
dir.items = make(map[string]Node)
|
||||
})
|
||||
}
|
||||
d.forgetDirPath(relativePath)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ func TestDirForgetAll(t *testing.T) {
|
|||
dir.ForgetAll()
|
||||
assert.Equal(t, 1, len(root.items))
|
||||
assert.Equal(t, 0, len(dir.items))
|
||||
assert.True(t, root.read.IsZero())
|
||||
assert.False(t, root.read.IsZero())
|
||||
assert.True(t, dir.read.IsZero())
|
||||
|
||||
root.ForgetAll()
|
||||
|
@ -521,6 +521,22 @@ func TestDirRename(t *testing.T) {
|
|||
file1.Path = "dir2/file3"
|
||||
fstest.CheckListingWithPrecision(t, r.Fremote, []fstest.Item{file1}, []string{"dir2"}, r.Fremote.Precision())
|
||||
|
||||
// rename an empty directory
|
||||
_, err = root.Mkdir("empty directory")
|
||||
assert.NoError(t, err)
|
||||
checkListing(t, root, []string{
|
||||
"dir2,0,true",
|
||||
"empty directory,0,true",
|
||||
})
|
||||
err = root.Rename("empty directory", "renamed empty directory", root)
|
||||
assert.NoError(t, err)
|
||||
checkListing(t, root, []string{
|
||||
"dir2,0,true",
|
||||
"renamed empty directory,0,true",
|
||||
})
|
||||
// ...we don't check the underlying f.Fremote because on
|
||||
// bucket based remotes the directory won't be there
|
||||
|
||||
// read only check
|
||||
vfs.Opt.ReadOnly = true
|
||||
err = dir.Rename("potato", "tuba", dir)
|
||||
|
|
Loading…
Reference in New Issue
Block a user