mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
sys: FspVolumeNotify: allow multiple outstanding calls to FspFileSystemNotifyBegin
This commit is contained in:
parent
73f587e674
commit
228f1d658d
@ -419,7 +419,7 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject)
|
||||
Result = FspNotifyInitializeSync(&FsvolDeviceExtension->NotifySync);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
FspWgroupInitialize(&FsvolDeviceExtension->VolumeNotifyWgroup);
|
||||
ExInitializeFastMutex(&FsvolDeviceExtension->VolumeNotifyMutex);
|
||||
InitializeListHead(&FsvolDeviceExtension->NotifyList);
|
||||
FsvolDeviceExtension->InitDoneNotify = 1;
|
||||
|
||||
|
@ -1190,8 +1190,8 @@ typedef struct
|
||||
KSPIN_LOCK InfoSpinLock;
|
||||
UINT64 InfoExpirationTime;
|
||||
FSP_FSCTL_VOLUME_INFO VolumeInfo;
|
||||
LONG VolumeNotifyLock;
|
||||
FSP_WGROUP VolumeNotifyWgroup;
|
||||
FAST_MUTEX VolumeNotifyMutex;
|
||||
LONG VolumeNotifyCount;
|
||||
PNOTIFY_SYNC NotifySync;
|
||||
LIST_ENTRY NotifyList;
|
||||
FSP_STATISTICS *Statistics;
|
||||
|
@ -476,10 +476,12 @@ static VOID FspVolumeDeleteNoLock(
|
||||
FspMupUnregister(Globals->FsmupDeviceObject, FsvolDeviceObject);
|
||||
}
|
||||
|
||||
/* release the volume notify lock if held (so that any pending rename will abort) */
|
||||
FspWgroupSignalPermanently(&FsvolDeviceExtension->VolumeNotifyWgroup);
|
||||
if (1 == InterlockedCompareExchange(&FsvolDeviceExtension->VolumeNotifyLock, 0, 1))
|
||||
FspFsvolDeviceFileRenameReleaseOwner(FsvolDeviceObject, FsvolDeviceObject);
|
||||
ExAcquireFastMutex(&FsvolDeviceExtension->VolumeNotifyMutex);
|
||||
if (1 <= FsvolDeviceExtension->VolumeNotifyCount)
|
||||
FspFsvolDeviceFileRenameReleaseOwner(FsvolDeviceObject,
|
||||
&FsvolDeviceExtension->VolumeNotifyCount);
|
||||
FsvolDeviceExtension->VolumeNotifyCount = -1;
|
||||
ExReleaseFastMutex(&FsvolDeviceExtension->VolumeNotifyMutex);
|
||||
|
||||
/* release the volume device object */
|
||||
FspDeviceDereference(FsvolDeviceObject);
|
||||
@ -1122,7 +1124,6 @@ NTSTATUS FspVolumeNotify(
|
||||
ASSERT(0 != IrpSp->FileObject->FsContext2);
|
||||
|
||||
PDEVICE_OBJECT FsvolDeviceObject = IrpSp->FileObject->FsContext2;
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||
PVOID InputBuffer = IrpSp->Parameters.FileSystemControl.Type3InputBuffer;
|
||||
ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength;
|
||||
FSP_VOLUME_NOTIFY_WORK_ITEM *NotifyWorkItem = 0;
|
||||
@ -1158,7 +1159,6 @@ NTSTATUS FspVolumeNotify(
|
||||
ExInitializeWorkItem(&NotifyWorkItem->WorkItem, FspVolumeNotifyWork, NotifyWorkItem);
|
||||
NotifyWorkItem->FsvolDeviceObject = FsvolDeviceObject;
|
||||
|
||||
FspWgroupIncrement(&FsvolDeviceExtension->VolumeNotifyWgroup);
|
||||
ExQueueWorkItem(&NotifyWorkItem->WorkItem, DelayedWorkQueue);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
@ -1177,11 +1177,6 @@ static NTSTATUS FspVolumeNotifyLock(
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
NTSTATUS Result;
|
||||
|
||||
if (!FspDeviceReference(FsvolDeviceObject))
|
||||
return STATUS_CANCELLED;
|
||||
|
||||
/*
|
||||
* Acquire the rename lock shared to disallow concurrent RENAME's.
|
||||
*
|
||||
@ -1190,19 +1185,28 @@ static NTSTATUS FspVolumeNotifyLock(
|
||||
* that the file is not open and not invalidate its caches, whereas the
|
||||
* file has simply changed name.
|
||||
*/
|
||||
Result = STATUS_CANT_WAIT;
|
||||
if (FspFsvolDeviceFileRenameTryAcquireShared(FsvolDeviceObject))
|
||||
{
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||
|
||||
if (0 == InterlockedCompareExchange(&FsvolDeviceExtension->VolumeNotifyLock, 1, 0))
|
||||
if (!FspDeviceReference(FsvolDeviceObject))
|
||||
return STATUS_CANCELLED;
|
||||
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||
NTSTATUS Result = STATUS_SUCCESS;
|
||||
|
||||
ExAcquireFastMutex(&FsvolDeviceExtension->VolumeNotifyMutex);
|
||||
if (0 == FsvolDeviceExtension->VolumeNotifyCount)
|
||||
{
|
||||
if (FspFsvolDeviceFileRenameTryAcquireShared(FsvolDeviceObject))
|
||||
{
|
||||
FspFsvolDeviceFileRenameSetOwner(FsvolDeviceObject, FsvolDeviceObject);
|
||||
Result = STATUS_SUCCESS;
|
||||
FspFsvolDeviceFileRenameSetOwner(FsvolDeviceObject,
|
||||
&FsvolDeviceExtension->VolumeNotifyCount);
|
||||
FsvolDeviceExtension->VolumeNotifyCount++;
|
||||
}
|
||||
else
|
||||
FspFsvolDeviceFileRenameRelease(FsvolDeviceObject);
|
||||
Result = STATUS_CANT_WAIT;
|
||||
}
|
||||
else if (0 < FsvolDeviceExtension->VolumeNotifyCount)
|
||||
FsvolDeviceExtension->VolumeNotifyCount++;
|
||||
ExReleaseFastMutex(&FsvolDeviceExtension->VolumeNotifyMutex);
|
||||
|
||||
FspDeviceDereference(FsvolDeviceObject);
|
||||
|
||||
@ -1297,13 +1301,19 @@ static VOID FspVolumeNotifyWork(PVOID NotifyWorkItem0)
|
||||
FspFree(FullFileName.Buffer);
|
||||
|
||||
FspFree(NotifyWorkItem);
|
||||
|
||||
FspWgroupDecrement(&FsvolDeviceExtension->VolumeNotifyWgroup);
|
||||
|
||||
if (Unlock)
|
||||
{
|
||||
FspWgroupWait(&FsvolDeviceExtension->VolumeNotifyWgroup, KernelMode, FALSE, 0);
|
||||
if (1 == InterlockedCompareExchange(&FsvolDeviceExtension->VolumeNotifyLock, 0, 1))
|
||||
FspFsvolDeviceFileRenameReleaseOwner(FsvolDeviceObject, FsvolDeviceObject);
|
||||
ExAcquireFastMutex(&FsvolDeviceExtension->VolumeNotifyMutex);
|
||||
if (1 == FsvolDeviceExtension->VolumeNotifyCount)
|
||||
{
|
||||
FspFsvolDeviceFileRenameReleaseOwner(FsvolDeviceObject,
|
||||
&FsvolDeviceExtension->VolumeNotifyCount);
|
||||
FsvolDeviceExtension->VolumeNotifyCount--;
|
||||
}
|
||||
else if (1 < FsvolDeviceExtension->VolumeNotifyCount)
|
||||
FsvolDeviceExtension->VolumeNotifyCount--;
|
||||
ExReleaseFastMutex(&FsvolDeviceExtension->VolumeNotifyMutex);
|
||||
}
|
||||
|
||||
FspDeviceDereference(FsvolDeviceObject);
|
||||
|
@ -38,7 +38,7 @@ void notify_abandon_dotest(ULONG Flags)
|
||||
ASSERT(STATUS_SUCCESS == Result);
|
||||
|
||||
Result = FspFsctlNotify(FileSystem->VolumeHandle, 0, 0);
|
||||
ASSERT(STATUS_CANT_WAIT == Result);
|
||||
ASSERT(STATUS_SUCCESS == Result);
|
||||
|
||||
memfs_stop(memfs);
|
||||
}
|
||||
@ -111,6 +111,8 @@ void notify_abandon_rename_test(void)
|
||||
notify_abandon_rename_dotest(MemfsNet, L"\\\\memfs\\share");
|
||||
}
|
||||
|
||||
/* OBSOLETE: it is now possible to have multiple outstanding NotifyBegin() calls. */
|
||||
#if 0
|
||||
static
|
||||
void notify_timeout_dotest(ULONG Flags)
|
||||
{
|
||||
@ -150,6 +152,7 @@ void notify_timeout_test(void)
|
||||
if (WinFspNetTests)
|
||||
notify_timeout_dotest(MemfsNet);
|
||||
}
|
||||
#endif
|
||||
|
||||
static
|
||||
void notify_change_dotest(ULONG Flags)
|
||||
@ -453,7 +456,10 @@ void notify_tests(void)
|
||||
|
||||
TEST(notify_abandon_test);
|
||||
TEST(notify_abandon_rename_test);
|
||||
/* OBSOLETE: it is now possible to have multiple outstanding NotifyBegin() calls. */
|
||||
#if 0
|
||||
TEST(notify_timeout_test);
|
||||
#endif
|
||||
TEST(notify_change_test);
|
||||
TEST(notify_open_change_test);
|
||||
TEST(notify_dirnotify_test);
|
||||
|
Loading…
x
Reference in New Issue
Block a user