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:
Bill Zissimopoulos 2016-04-18 13:48:50 -07:00
parent 6dd6ec6b47
commit c40ce93fe2
4 changed files with 63 additions and 33 deletions

View File

@ -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;

View File

@ -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")

View File

@ -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;

View File

@ -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;
}