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