From 2bb834901cbb71569579fe4a0b48d5b85ad1e54e Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Fri, 17 Oct 2008 13:42:48 +0000 Subject: [PATCH] Fix two bugs related to the use of the entry cache for parent entries in BFS: * The parent entry ("..") of a directory was not removed from the cache when its directory was removed. * When moving a directory to a new parent, it's cached parent entry wasn't updated. Those would lead to stale cache entries for directory parents. If a certain inode would be reused to create a new directory after removing another, this would lead to an invalid inode being returned when looking up the parent of the new directory. This was easily reproducible by unzipping some directory structure, deleting it and unzipping it again. You would end up with many "inode already deleted" messages. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28214 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp index b7d04328b9..2a9c44fc60 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -1110,6 +1110,11 @@ bfs_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName, && (status = inode->GetTree(&movedTree)) == B_OK) { status = movedTree->Replace(transaction, (const uint8*)"..", 2, newDirectory->ID()); + + if (status == B_OK) { + // update/add the cache entry for the parent + entry_cache_add(volume->ID(), id, "..", newDirectory->ID()); + } } if (status == B_OK) @@ -1477,7 +1482,10 @@ bfs_remove_dir(fs_volume* _volume, fs_vnode* _directory, const char* name) off_t id; status_t status = directory->Remove(transaction, name, &id, true); if (status == B_OK) { + // Remove the cache entry for the directory and potentially also + // the parent entry still belonging to the directory entry_cache_remove(volume->ID(), directory->ID(), name); + entry_cache_remove(volume->ID(), id, ".."); transaction.Done();