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

View File

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

View File

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

View File

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