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:
nielash 2024-04-28 07:47:24 -04:00 committed by Nick Craig-Wood
parent 3ae4534ce6
commit a56cd52025
2 changed files with 26 additions and 0 deletions

View File

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

View File

@ -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) {