From 86c44a0176e842ce239bd8d824d69e5c8d69d04c Mon Sep 17 00:00:00 2001 From: Jim906 Date: Sat, 27 Dec 2025 11:19:14 -0500 Subject: [PATCH] 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 Reviewed-by: waddlesplash --- src/add-ons/kernel/file_systems/fat/kernel_interface.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/add-ons/kernel/file_systems/fat/kernel_interface.cpp b/src/add-ons/kernel/file_systems/fat/kernel_interface.cpp index 39047d019e..5dc585a563 100644 --- a/src/add-ons/kernel/file_systems/fat/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/fat/kernel_interface.cpp @@ -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)