From dbaafd15c0679ad0c5dca0cc9b6a4decdd22fbeb Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Mon, 18 May 2015 22:58:30 +0200 Subject: [PATCH] fat: Remove directory from dlist on unlink, not in remove_vnode. The removal of the vnode happens later than the actual unlink. As part of the unlink, the vnode cache is already updated to mark the unlinked directory invalid. This means its entry in the directory list needs to be removed as well. Otherwise, if a directory list entry is looked up in the time between unlink and remove_vnode, the assertion which checks the validity of the directory list entries would fail. --- src/add-ons/kernel/file_systems/fat/file.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/add-ons/kernel/file_systems/fat/file.c b/src/add-ons/kernel/file_systems/fat/file.c index a6a2bf942b..77a8d2c4fa 100644 --- a/src/add-ons/kernel/file_systems/fat/file.c +++ b/src/add-ons/kernel/file_systems/fat/file.c @@ -1072,9 +1072,10 @@ dosfs_remove_vnode(fs_volume *_vol, fs_vnode *_node, bool reenter) if (find_vnid_in_vcache(vol, node->vnid) == B_OK) remove_from_vcache(vol, node->vnid); - /* and from the dlist as well */ - if (node->mode & FAT_SUBDIR) - dlist_remove(vol, node->vnid); + /* at this point, the node shouldn't be in the dlist anymore */ + if ((node->mode & FAT_SUBDIR) != 0) { + ASSERT(dlist_find(vol, CLUSTER_OF_DIR_CLUSTER_VNID(node->vnid)) == -1); + } free(node); @@ -1174,6 +1175,9 @@ do_unlink(fs_volume *_vol, fs_vnode *_dir, const char *name, bool is_file) */ vcache_set_entry(vol, file->vnid, generate_unique_vnid(vol)); + if (!is_file) + dlist_remove(vol, file->vnid); + // fsil doesn't call dosfs_write_vnode for us, so we have to free the // vnode manually here. remove_vnode(_vol, file->vnid);