From 8ffe897891b6584fb7884d8173e95855fc88aa08 Mon Sep 17 00:00:00 2001 From: Mike Lubinets Date: Thu, 12 Oct 2023 14:17:10 +0400 Subject: [PATCH 1/2] unlink the new path from the replaced inode in rename --- src/inode_table.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/inode_table.rs b/src/inode_table.rs index 50c82cd..b981382 100644 --- a/src/inode_table.rs +++ b/src/inode_table.rs @@ -165,7 +165,9 @@ impl InodeTable { lookups = entry.lookups; if lookups == 0 { delete = true; - self.by_path.remove(entry.path.as_ref().unwrap()); + if let Some(path) = entry.path.as_ref() { + self.by_path.remove(path); + } } } @@ -180,9 +182,15 @@ impl InodeTable { /// Change an inode's path to a different one, without changing the inode number. /// Lookup counts remain unchanged, even if this is replacing another file. pub fn rename(&mut self, oldpath: &Path, newpath: Arc) { + // replace the old path with the new one let idx = self.by_path.remove(Pathish::new(oldpath)).unwrap(); self.table[idx].path = Some(newpath.clone()); - self.by_path.insert(newpath, idx); // this can replace a path with a new inode + let prev = self.by_path.insert(newpath, idx); // this can replace a path with a new inode + + // unlink the new path from the previous inode holding it + if let Some(prev) = prev { + self.table[prev].path = None; + } } /// Remove the path->inode mapping for a given path, but keep the inode around. From 749f461e14f4ada5cb004f6d876bce8b8b8ae3d6 Mon Sep 17 00:00:00 2001 From: Mike Lubinets Date: Thu, 12 Oct 2023 15:56:09 +0400 Subject: [PATCH 2/2] unlink the new path from unlinked inode --- src/inode_table.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/inode_table.rs b/src/inode_table.rs index b981382..a50a8d8 100644 --- a/src/inode_table.rs +++ b/src/inode_table.rs @@ -195,8 +195,8 @@ impl InodeTable { /// Remove the path->inode mapping for a given path, but keep the inode around. pub fn unlink(&mut self, path: &Path) { - self.by_path.remove(Pathish::new(path)); - // Note that the inode->path mapping remains. + let idx = self.by_path.remove(Pathish::new(path)).unwrap(); + self.table[idx].path = None; } /// Get a free indode table entry and its number, either by allocating a new one, or re-using