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:
@@ -74,6 +74,7 @@ CONTRIBUTOR LIST
|
|||||||
|Ronny Chan |ronny at ronnychan.ca
|
|Ronny Chan |ronny at ronnychan.ca
|
||||||
|Sam Kelly (DuroSoft Technologies LLC, https://durosoft.com) |sam at durosoft.com
|
|Sam Kelly (DuroSoft Technologies LLC, https://durosoft.com) |sam at durosoft.com
|
||||||
|Santiago Ganis |sganis at gmail.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
|
|Thomas Gibson-Robinson |tom at cocotec.io
|
||||||
|Tobias Urlaub |saibotu at outlook.de
|
|Tobias Urlaub |saibotu at outlook.de
|
||||||
|Victor Gao |victgm at outlook.com
|
|Victor Gao |victgm at outlook.com
|
||||||
|
|||||||
@@ -1363,6 +1363,24 @@ BOOLEAN FspFsvolDeviceFileRenameTryAcquireExclusive(PDEVICE_OBJECT DeviceObject)
|
|||||||
return ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->FileRenameResource, FALSE);
|
return ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->FileRenameResource, FALSE);
|
||||||
}
|
}
|
||||||
static inline
|
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)
|
VOID FspFsvolDeviceFileRenameSetOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner)
|
||||||
{
|
{
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
||||||
|
|||||||
+9
-1
@@ -1502,7 +1502,15 @@ static VOID FspVolumeNotifyWork(PVOID NotifyWorkItem0)
|
|||||||
BOOLEAN Unlock = FALSE;
|
BOOLEAN Unlock = FALSE;
|
||||||
NTSTATUS Result;
|
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 */
|
/* iterate over notify information and invalidate/notify each file */
|
||||||
for (; (PUINT8)NotifyInfo + sizeof(NotifyInfo->Size) <= NotifyInfoEnd;
|
for (; (PUINT8)NotifyInfo + sizeof(NotifyInfo->Size) <= NotifyInfoEnd;
|
||||||
|
|||||||
Reference in New Issue
Block a user