fat: Fix potential double lock

* Unlock the volume once the directories are locked in dosfs_rename.
  At that point locking the volume has served its purpose.
* If the volume lock is retained throughout dosfs_rename, a double
  lock can occur in dosfs_read_vnode, in the event that one of the
  involved file nodes has not already been constructed prior to the
  rename.
* Fixes #19614.

Change-Id: Ib679a6f3ba3dc8f87fb0c6263eb82d2d06cb6064
Reviewed-on: https://review.haiku-os.org/c/haiku/+/10166
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Jim906
2025-12-27 23:39:20 +00:00
committed by waddlesplash
parent ffa620b2b5
commit 86c44a0176
@@ -1376,15 +1376,15 @@ dosfs_rename(fs_volume* volume, fs_vnode* fromDir, const char* fromName, fs_vnod
ComponentName fromBsdName(ISLASTCN, NOCRED, RENAME, 0, fromName);
ComponentName toBsdName(ISLASTCN, NOCRED, RENAME, 0, toName);
// Don't do 2 renames at the same time on the same volume. If moving to a new directory,
// and the destination directory of one thread is the origin directory of the other,
// and vice versa, a deadlock can occur.
// Eliminate the possibility that two move operations could deadlock, if they are
// locking the same two directories in the reverse order.
MutexLocker volumeLocker(bsdVolume->mnt_mtx.haikuMutex);
WriteLocker fromDirLocker(fromDirBsdNode->v_vnlock->haikuRW);
WriteLocker toDirLocker;
if (fromDirBsdNode != toDirBsdNode)
toDirLocker.SetTo(toDirBsdNode->v_vnlock->haikuRW, false);
volumeLocker.Unlock();
status_t status = _dosfs_access(bsdVolume, fromDirBsdNode, W_OK);
if (status == B_OK && fromDirBsdNode != toDirBsdNode)