mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-29 19:18:39 -05:00 
			
		
		
		
	sys: FspVolumeNotify: allow multiple outstanding calls to FspFileSystemNotifyBegin
This commit is contained in:
		| @@ -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 (!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)) | ||||
|         { | ||||
|         FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); | ||||
|  | ||||
|         if (0 == InterlockedCompareExchange(&FsvolDeviceExtension->VolumeNotifyLock, 1, 0)) | ||||
|         { | ||||
|             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); | ||||
|  | ||||
| @@ -1298,12 +1302,18 @@ static VOID FspVolumeNotifyWork(PVOID NotifyWorkItem0) | ||||
|  | ||||
|     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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user