mirror of
https://github.com/rclone/rclone.git
synced 2024-11-25 01:44:41 +01:00
vfs: fix renaming a directory
Before this change, renaming a directory d failed to rename its key in d.parent.items, which caused trouble later when doing Dir.Stat on a subdirectory. This change fixes the issue.
This commit is contained in:
parent
3ae4534ce6
commit
a56cd52025
13
vfs/dir.go
13
vfs/dir.go
@ -371,7 +371,9 @@ func (d *Dir) renameTree(dirPath string) {
|
|||||||
// Make sure the path is correct for each node
|
// Make sure the path is correct for each node
|
||||||
if d.path != dirPath {
|
if d.path != dirPath {
|
||||||
fs.Debugf(d.path, "Renaming to %q", dirPath)
|
fs.Debugf(d.path, "Renaming to %q", dirPath)
|
||||||
|
delete(d.parent.items, name(d.path))
|
||||||
d.path = dirPath
|
d.path = dirPath
|
||||||
|
d.parent.items[name(d.path)] = d
|
||||||
d.entry = fs.NewDirCopy(context.TODO(), d.entry).SetRemote(dirPath)
|
d.entry = fs.NewDirCopy(context.TODO(), d.entry).SetRemote(dirPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,6 +406,8 @@ func (d *Dir) rename(newParent *Dir, fsDir fs.Directory) {
|
|||||||
d.entry = fsDir
|
d.entry = fsDir
|
||||||
d.path = fsDir.Remote()
|
d.path = fsDir.Remote()
|
||||||
newPath := d.path
|
newPath := d.path
|
||||||
|
delete(d.parent.items, name(oldPath))
|
||||||
|
d.parent.items[name(d.path)] = d
|
||||||
d.read = time.Time{}
|
d.read = time.Time{}
|
||||||
d.mu.Unlock()
|
d.mu.Unlock()
|
||||||
|
|
||||||
@ -418,6 +422,15 @@ func (d *Dir) rename(newParent *Dir, fsDir fs.Directory) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// convert path to name
|
||||||
|
func name(p string) string {
|
||||||
|
p = path.Base(p)
|
||||||
|
if p == "." {
|
||||||
|
p = "/"
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
// addObject adds a new object or directory to the directory
|
// addObject adds a new object or directory to the directory
|
||||||
//
|
//
|
||||||
// The name passed in is marked as virtual as it hasn't been read from a remote
|
// The name passed in is marked as virtual as it hasn't been read from a remote
|
||||||
|
@ -589,6 +589,19 @@ func TestDirRename(t *testing.T) {
|
|||||||
vfs.Opt.ReadOnly = true
|
vfs.Opt.ReadOnly = true
|
||||||
err = dir.Rename("potato", "tuba", dir)
|
err = dir.Rename("potato", "tuba", dir)
|
||||||
assert.Equal(t, EROFS, err)
|
assert.Equal(t, EROFS, err)
|
||||||
|
|
||||||
|
// Rename a dir, check that key was correctly renamed in dir.parent.items
|
||||||
|
vfs.Opt.ReadOnly = false
|
||||||
|
_, ok := dir.parent.items["dir2"]
|
||||||
|
assert.True(t, ok, "dir.parent.items should have 'dir2' key before rename")
|
||||||
|
_, ok = dir.parent.items["dir3"]
|
||||||
|
assert.False(t, ok, "dir.parent.items should not have 'dir3' key before rename")
|
||||||
|
dir.renameTree("dir3") // rename dir2 to dir3
|
||||||
|
_, ok = dir.parent.items["dir2"]
|
||||||
|
assert.False(t, ok, "dir.parent.items should not have 'dir2' key after rename")
|
||||||
|
d, ok := dir.parent.items["dir3"]
|
||||||
|
assert.True(t, ok, fmt.Sprintf("expected to find 'dir3' key in dir.parent.items after rename, got %v", dir.parent.items))
|
||||||
|
assert.Equal(t, dir, d, `expected renamed dir to match value of dir.parent.items["dir3"]`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDirStructSize(t *testing.T) {
|
func TestDirStructSize(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user