From 1284e971e2a0843e910a3ffbbb0bc3023a57d7e0 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Sat, 29 Oct 2022 13:41:21 -0400 Subject: [PATCH] kernel/vfs: Fix locking behavior in acquire_vnode and add a missing ASSERT. vnode deletion is prevent either by owning a reference to the node, or by being at least a reader of the vnodes lock. Thus, in acquire_vnode, we have to inc_ref_count while still holding the lock in order to prevent a race. This function is used so rarely and quite deep inside FS drivers that I'm not sure this race would ever have been a problem. Nonetheless the old code was incorrect. --- src/system/kernel/fs/vfs.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index e48f1b927d..46166801ca 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -899,6 +899,8 @@ remove_vnode_from_mount_list(struct vnode* vnode, struct fs_mount* mount) static struct vnode* lookup_vnode(dev_t mountID, ino_t vnodeID) { + ASSERT_READ_LOCKED_RW_LOCK(&sVnodeLock); + struct vnode_hash_key key; key.device = mountID; @@ -3894,12 +3896,9 @@ get_vnode(fs_volume* volume, ino_t vnodeID, void** _privateNode) extern "C" status_t acquire_vnode(fs_volume* volume, ino_t vnodeID) { - struct vnode* vnode; - - rw_lock_read_lock(&sVnodeLock); - vnode = lookup_vnode(volume->id, vnodeID); - rw_lock_read_unlock(&sVnodeLock); + ReadLocker nodeLocker(sVnodeLock); + struct vnode* vnode = lookup_vnode(volume->id, vnodeID); if (vnode == NULL) return B_BAD_VALUE;