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.
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user