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