1
0
mirror of https://github.com/winfsp/winfsp.git synced 2026-06-24 21:42:33 -05:00

Merge pull request #669 from yeonsh/fix-notify-rename-selfdeadlock

sys: fix FileRenameResource self-deadlock between notify session and FspVolumeNotifyWork
This commit is contained in:
Bill Zissimopoulos
2026-06-23 15:21:41 +03:00
committed by GitHub
3 changed files with 28 additions and 1 deletions
+1
View File
@@ -74,6 +74,7 @@ CONTRIBUTOR LIST
|Ronny Chan |ronny at ronnychan.ca
|Sam Kelly (DuroSoft Technologies LLC, https://durosoft.com) |sam at durosoft.com
|Santiago Ganis |sganis at gmail.com
|Seunghoon Yeon (Bdrive Inc, https://www.bdrive.com) |ysh at bdrive.com
|Thomas Gibson-Robinson |tom at cocotec.io
|Tobias Urlaub |saibotu at outlook.de
|Victor Gao |victgm at outlook.com
+18
View File
@@ -1363,6 +1363,24 @@ BOOLEAN FspFsvolDeviceFileRenameTryAcquireExclusive(PDEVICE_OBJECT DeviceObject)
return ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->FileRenameResource, FALSE);
}
static inline
VOID FspFsvolDeviceFileRenameAcquireSharedStarveExclusive(PDEVICE_OBJECT DeviceObject)
{
/*
* Acquire the file rename resource shared, but starve (ignore) any QUEUED
* exclusive waiter. Used by FspVolumeNotifyWork: a notify session opened by
* FspFileSystemNotifyBegin already holds this resource shared (via owner
* pointer) and intentionally defers renames until FspFileSystemNotifyEnd. A
* plain ExAcquireResourceSharedLite here would honor a concurrently queued
* exclusive rename waiter and block -- but the very work item that blocks is
* the one that must run FspFileSystemNotifyEnd processing to release the
* session and let that rename proceed, so the two self-deadlock. Starving the
* queued exclusive waiter is safe: the rename stays blocked behind the shared
* holders either way, so name stability across the notify is preserved.
*/
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
ExAcquireSharedStarveExclusive(&FsvolDeviceExtension->FileRenameResource, TRUE);
}
static inline
VOID FspFsvolDeviceFileRenameSetOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner)
{
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
+9 -1
View File
@@ -1502,7 +1502,15 @@ static VOID FspVolumeNotifyWork(PVOID NotifyWorkItem0)
BOOLEAN Unlock = FALSE;
NTSTATUS Result;
FspFsvolDeviceFileRenameAcquireShared(FsvolDeviceObject);
/*
* Starve queued exclusive (rename) waiters here to avoid a self-deadlock:
* the enclosing FspFileSystemNotifyBegin/End session already holds this
* resource shared, and a rename that queues exclusive mid-session would
* otherwise block this work item -- the same work item that must release
* the session (FspVolumeNotifyLock count) and unblock that rename. See
* FspFsvolDeviceFileRenameAcquireSharedStarveExclusive.
*/
FspFsvolDeviceFileRenameAcquireSharedStarveExclusive(FsvolDeviceObject);
/* iterate over notify information and invalidate/notify each file */
for (; (PUINT8)NotifyInfo + sizeof(NotifyInfo->Size) <= NotifyInfoEnd;