mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -05:00 
			
		
		
		
	sys: major change in device management: introduce FspDeviceGlobalLock and remove FSP_FSVOL_DEVICE_EXTENSION::DeleteResource; makes locking coarse-grained but more generic and safe
This commit is contained in:
		| @@ -320,10 +320,6 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject) | ||||
|         FsvolDeviceExtension->InitDoneFsvrt = 1; | ||||
|     } | ||||
|  | ||||
|     /* initialize our delete lock */ | ||||
|     ExInitializeResourceLite(&FsvolDeviceExtension->DeleteResource); | ||||
|     FsvolDeviceExtension->InitDoneDelRsc = 1; | ||||
|  | ||||
|     /* create our Ioq */ | ||||
|     IrpTimeout.QuadPart = FsvolDeviceExtension->VolumeParams.IrpTimeout * 10000ULL; | ||||
|         /* convert millis to nanos */ | ||||
| @@ -441,10 +437,6 @@ static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject) | ||||
|         ExDeleteResourceLite(&FsvolDeviceExtension->FileRenameResource); | ||||
|     } | ||||
|  | ||||
|     /* finalize our delete lock */ | ||||
|     if (FsvolDeviceExtension->InitDoneDelRsc) | ||||
|         ExDeleteResourceLite(&FsvolDeviceExtension->DeleteResource); | ||||
|  | ||||
|     /* is there a virtual disk? */ | ||||
|     if (FsvolDeviceExtension->InitDoneFsvrt) | ||||
|     { | ||||
| @@ -938,3 +930,5 @@ VOID FspDeviceDeleteAll(VOID) | ||||
|  | ||||
|     FspDeviceDeleteList(DeviceObjects, DeviceObjectCount); | ||||
| } | ||||
|  | ||||
| ERESOURCE FspDeviceGlobalResource; | ||||
|   | ||||
| @@ -36,6 +36,7 @@ NTSTATUS DriverEntry( | ||||
|     FspDriverMultiVersionInitialize(); | ||||
|  | ||||
|     FspDriverObject = DriverObject; | ||||
|     ExInitializeResourceLite(&FspDeviceGlobalResource); | ||||
|  | ||||
|     /* create the file system control device objects */ | ||||
|     UNICODE_STRING DeviceSddl; | ||||
| @@ -182,8 +183,9 @@ VOID FspUnload( | ||||
|  | ||||
|     FspFsctlDiskDeviceObject = 0; | ||||
|     FspFsctlNetDeviceObject = 0; | ||||
|     FspDeviceDeleteAll(); | ||||
|     //FspDeviceDeleteAll(); | ||||
|  | ||||
|     ExDeleteResourceLite(&FspDeviceGlobalResource); | ||||
|     FspDriverObject = 0; | ||||
|  | ||||
| #pragma prefast(suppress:28175, "We are in DriverUnload: ok to access DriverName") | ||||
|   | ||||
| @@ -742,14 +742,13 @@ typedef struct | ||||
| typedef struct | ||||
| { | ||||
|     FSP_DEVICE_EXTENSION Base; | ||||
|     UINT32 InitDoneFsvrt:1, InitDoneDelRsc:1, InitDoneIoq:1, InitDoneSec:1, InitDoneDir:1, | ||||
|     UINT32 InitDoneFsvrt:1, InitDoneIoq:1, InitDoneSec:1, InitDoneDir:1, | ||||
|         InitDoneCtxTab:1, InitDoneTimer:1, InitDoneInfo:1, InitDoneNotify:1; | ||||
|     PDEVICE_OBJECT FsctlDeviceObject; | ||||
|     PDEVICE_OBJECT FsvrtDeviceObject; | ||||
|     HANDLE MupHandle; | ||||
|     PVPB SwapVpb; | ||||
|     FSP_DELAYED_WORK_ITEM DeleteVolumeDelayedWorkItem; | ||||
|     ERESOURCE DeleteResource; | ||||
|     FSP_FSCTL_VOLUME_PARAMS VolumeParams; | ||||
|     UNICODE_STRING VolumePrefix; | ||||
|     FSP_IOQ *Ioq; | ||||
| @@ -825,6 +824,18 @@ NTSTATUS FspDeviceCopyList( | ||||
| VOID FspDeviceDeleteList( | ||||
|     PDEVICE_OBJECT *DeviceObjects, ULONG DeviceObjectCount); | ||||
| VOID FspDeviceDeleteAll(VOID); | ||||
| static inline | ||||
| VOID FspDeviceGlobalLock(VOID) | ||||
| { | ||||
|     extern ERESOURCE FspDeviceGlobalResource; | ||||
|     ExAcquireResourceExclusiveLite(&FspDeviceGlobalResource, TRUE); | ||||
| } | ||||
| static inline | ||||
| VOID FspDeviceGlobalUnlock(VOID) | ||||
| { | ||||
|     extern ERESOURCE FspDeviceGlobalResource; | ||||
|     ExReleaseResourceLite(&FspDeviceGlobalResource); | ||||
| } | ||||
| #define FspFsvolDeviceStoppedStatus(DeviceObject)\ | ||||
|     STATUS_VOLUME_DISMOUNTED | ||||
|     //(FILE_DEVICE_DISK_FILE_SYSTEM == (DeviceObject)->DeviceType ?\ | ||||
| @@ -1021,6 +1032,7 @@ extern FAST_IO_DISPATCH FspFastIoDispatch; | ||||
| extern CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks; | ||||
| extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[]; | ||||
| extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[]; | ||||
| extern ERESOURCE FspDeviceGlobalResource; | ||||
| extern WCHAR FspFileDescDirectoryPatternMatchAll[]; | ||||
| extern FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache; | ||||
|  | ||||
|   | ||||
| @@ -8,12 +8,18 @@ | ||||
|  | ||||
| NTSTATUS FspVolumeCreate( | ||||
|     PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); | ||||
| static NTSTATUS FspVolumeCreateNoLock( | ||||
|     PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); | ||||
| static WORKER_THREAD_ROUTINE FspVolumeCreateRegisterMup; | ||||
| VOID FspVolumeDelete( | ||||
|     PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); | ||||
| static VOID FspVolumeDeleteNoLock( | ||||
|     PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); | ||||
| static WORKER_THREAD_ROUTINE FspVolumeDeleteDelayed; | ||||
| NTSTATUS FspVolumeMount( | ||||
|     PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); | ||||
| static NTSTATUS FspVolumeMountNoLock( | ||||
|     PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); | ||||
| NTSTATUS FspVolumeRedirQueryPathEx( | ||||
|     PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); | ||||
| NTSTATUS FspVolumeGetName( | ||||
| @@ -27,14 +33,17 @@ NTSTATUS FspVolumeWork( | ||||
|  | ||||
| #ifdef ALLOC_PRAGMA | ||||
| #pragma alloc_text(PAGE, FspVolumeCreate) | ||||
| #pragma alloc_text(PAGE, FspVolumeCreateNoLock) | ||||
| #pragma alloc_text(PAGE, FspVolumeCreateRegisterMup) | ||||
| // ! #pragma alloc_text(PAGE, FspVolumeDelete) | ||||
| // ! #pragma alloc_text(PAGE, FspVolumeDeleteNoLock) | ||||
| // ! #pragma alloc_text(PAGE, FspVolumeDeleteDelayed) | ||||
| // ! #pragma alloc_text(PAGE, FspVolumeMount) | ||||
| // ! #pragma alloc_text(PAGE, FspVolumeMountNoLock) | ||||
| #pragma alloc_text(PAGE, FspVolumeRedirQueryPathEx) | ||||
| #pragma alloc_text(PAGE, FspVolumeGetName) | ||||
| #pragma alloc_text(PAGE, FspVolumeTransact) | ||||
| #pragma alloc_text(PAGE, FspVolumeStop) | ||||
| #pragma alloc_text(PAGE, FspVolumeRedirQueryPathEx) | ||||
| #pragma alloc_text(PAGE, FspVolumeWork) | ||||
| #endif | ||||
|  | ||||
| @@ -50,6 +59,16 @@ typedef struct | ||||
|  | ||||
| NTSTATUS FspVolumeCreate( | ||||
|     PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) | ||||
| { | ||||
|     NTSTATUS Result; | ||||
|     FspDeviceGlobalLock(); | ||||
|     Result = FspVolumeCreateNoLock(FsctlDeviceObject, Irp, IrpSp); | ||||
|     FspDeviceGlobalUnlock(); | ||||
|     return Result; | ||||
| } | ||||
|  | ||||
| static NTSTATUS FspVolumeCreateNoLock( | ||||
|     PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) | ||||
| { | ||||
|     PAGED_CODE(); | ||||
|  | ||||
| @@ -239,6 +258,14 @@ static VOID FspVolumeCreateRegisterMup(PVOID Context) | ||||
|  | ||||
| VOID FspVolumeDelete( | ||||
|     PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) | ||||
| { | ||||
|     FspDeviceGlobalLock(); | ||||
|     FspVolumeDeleteNoLock(FsctlDeviceObject, Irp, IrpSp); | ||||
|     FspDeviceGlobalUnlock(); | ||||
| } | ||||
|  | ||||
| static VOID FspVolumeDeleteNoLock( | ||||
|     PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) | ||||
| { | ||||
|     // !PAGED_CODE(); | ||||
|  | ||||
| @@ -249,9 +276,6 @@ VOID FspVolumeDelete( | ||||
|     FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); | ||||
|     IrpSp->FileObject->FsContext2 = 0; | ||||
|  | ||||
|     /* acquire the volume device DeleteResource */ | ||||
|     ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->DeleteResource, TRUE); | ||||
|  | ||||
|     /* stop the I/O queue */ | ||||
|     FspIoqStop(FsvolDeviceExtension->Ioq); | ||||
|  | ||||
| @@ -319,9 +343,6 @@ VOID FspVolumeDelete( | ||||
|         FsvolDeviceExtension->MupHandle = 0; | ||||
|     } | ||||
|  | ||||
|     /* release the volume device DeleteResource */ | ||||
|     ExReleaseResourceLite(&FsvolDeviceExtension->DeleteResource); | ||||
|  | ||||
|     /* release the volume device object */ | ||||
|     FspDeviceDereference(FsvolDeviceObject); | ||||
| } | ||||
| @@ -344,9 +365,11 @@ static VOID FspVolumeDeleteDelayed(PVOID Context) | ||||
|     IoReleaseVpbSpinLock(Irql); | ||||
|     if (DeleteVpb) | ||||
|     { | ||||
|         FspDeviceGlobalLock(); | ||||
|         FspFreeExternal(FsvolDeviceExtension->SwapVpb); | ||||
|         FsvolDeviceExtension->SwapVpb = 0; | ||||
|         FspDeviceDereference(FsvolDeviceObject); | ||||
|         FspDeviceGlobalUnlock(); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
| @@ -357,6 +380,16 @@ static VOID FspVolumeDeleteDelayed(PVOID Context) | ||||
|  | ||||
| NTSTATUS FspVolumeMount( | ||||
|     PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) | ||||
| { | ||||
|     NTSTATUS Result; | ||||
|     FspDeviceGlobalLock(); | ||||
|     Result = FspVolumeMountNoLock(FsctlDeviceObject, Irp, IrpSp); | ||||
|     FspDeviceGlobalUnlock(); | ||||
|     return Result; | ||||
| } | ||||
|  | ||||
| static NTSTATUS FspVolumeMountNoLock( | ||||
|     PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) | ||||
| { | ||||
|     // !PAGED_CODE(); | ||||
|  | ||||
| @@ -386,14 +419,12 @@ NTSTATUS FspVolumeMount( | ||||
|                     FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); | ||||
|                     if (FsvolDeviceExtension->FsvrtDeviceObject == FsvrtDeviceObject) | ||||
|                     { | ||||
|                         ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->DeleteResource, TRUE); | ||||
|                         if (!FspIoqStopped(FsvolDeviceExtension->Ioq)) | ||||
|                         { | ||||
|                             Result = STATUS_SUCCESS; | ||||
|                             /* break out of the loop without FspDeviceDereference or DeleteResource release! */ | ||||
|                             /* break out of the loop without FspDeviceDereference */ | ||||
|                             break; | ||||
|                         } | ||||
|                         ExReleaseResourceLite(&FsvolDeviceExtension->DeleteResource); | ||||
|                     } | ||||
|                 } | ||||
|                 FspDeviceDereference(DeviceObjects[i]); | ||||
| @@ -405,10 +436,10 @@ NTSTATUS FspVolumeMount( | ||||
|  | ||||
|     /* | ||||
|      * At this point the volume device object we are going to use in the VPB | ||||
|      * has been FspDeviceReference'ed and the volume DeleteResource has been acquired. | ||||
|      * has been FspDeviceReference'd. | ||||
|      * | ||||
|      * We will increment the VPB's ReferenceCount so that we can do a delayed delete | ||||
|      * of the volume device later on. Once done with the VPB we can release the | ||||
|      * DeleteResource. [The volume device remains FspDeviceReference'ed!] | ||||
|      * of the volume device later on. | ||||
|      */ | ||||
|     ASSERT(0 != FsvolDeviceObject && 0 != FsvolDeviceExtension); | ||||
|     IoAcquireVpbSpinLock(&Irql); | ||||
| @@ -417,9 +448,6 @@ NTSTATUS FspVolumeMount( | ||||
|     Vpb->SerialNumber = FsvolDeviceExtension->VolumeParams.VolumeSerialNumber; | ||||
|     IoReleaseVpbSpinLock(Irql); | ||||
|  | ||||
|     /* done with mounting; release the DeleteResource */ | ||||
|     ExReleaseResourceLite(&FsvolDeviceExtension->DeleteResource); | ||||
|  | ||||
|     Irp->IoStatus.Information = 0; | ||||
|     return STATUS_SUCCESS; | ||||
| } | ||||
| @@ -449,9 +477,6 @@ NTSTATUS FspVolumeRedirQueryPathEx( | ||||
|     NTSTATUS Result; | ||||
|     FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); | ||||
|  | ||||
|     /* acquire our DeleteResource */ | ||||
|     ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->DeleteResource, TRUE); | ||||
|  | ||||
|     Result = STATUS_BAD_NETWORK_PATH; | ||||
|     if (!FspIoqStopped(FsvolDeviceExtension->Ioq)) | ||||
|     { | ||||
| @@ -469,9 +494,6 @@ NTSTATUS FspVolumeRedirQueryPathEx( | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /* release the DeleteResource */ | ||||
|     ExReleaseResourceLite(&FsvolDeviceExtension->DeleteResource); | ||||
|  | ||||
|     return Result; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user