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