sys: FspIopDispatchRetryComplete()

This commit is contained in:
Bill Zissimopoulos 2016-01-26 19:52:36 -08:00
parent ffbe13e6d9
commit af5745d5fc
6 changed files with 74 additions and 9 deletions

View File

@ -14,6 +14,7 @@ static NTSTATUS FspFsvolCreate(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
FSP_IOPREP_DISPATCH FspFsvolCreatePrepare; FSP_IOPREP_DISPATCH FspFsvolCreatePrepare;
FSP_IOCMPL_DISPATCH FspFsvolCreateComplete; FSP_IOCMPL_DISPATCH FspFsvolCreateComplete;
FSP_IORETR_DISPATCH FspFsvolCreateRetryComplete;
static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request, static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request,
FSP_FILE_NODE *FileNode, FSP_FILE_DESC *FileDesc, PFILE_OBJECT FileObject); FSP_FILE_NODE *FileNode, FSP_FILE_DESC *FileDesc, PFILE_OBJECT FileObject);
static VOID FspFsvolCreatePostClose(FSP_FILE_DESC *FileDesc); static VOID FspFsvolCreatePostClose(FSP_FILE_DESC *FileDesc);
@ -28,6 +29,7 @@ FSP_DRIVER_DISPATCH FspCreate;
#pragma alloc_text(PAGE, FspFsvolCreate) #pragma alloc_text(PAGE, FspFsvolCreate)
#pragma alloc_text(PAGE, FspFsvolCreatePrepare) #pragma alloc_text(PAGE, FspFsvolCreatePrepare)
#pragma alloc_text(PAGE, FspFsvolCreateComplete) #pragma alloc_text(PAGE, FspFsvolCreateComplete)
#pragma alloc_text(PAGE, FspFsvolCreateRetryComplete)
#pragma alloc_text(PAGE, FspFsvolCreateTryOpen) #pragma alloc_text(PAGE, FspFsvolCreateTryOpen)
#pragma alloc_text(PAGE, FspFsvolCreatePostClose) #pragma alloc_text(PAGE, FspFsvolCreatePostClose)
#pragma alloc_text(PAGE, FspFsvolCreateRequestFini) #pragma alloc_text(PAGE, FspFsvolCreateRequestFini)
@ -711,6 +713,14 @@ VOID FspFsvolCreateComplete(
IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName); IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName);
} }
NTSTATUS FspFsvolCreateRetryComplete(
PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request)
{
PAGED_CODE();
return STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request, static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request,
FSP_FILE_NODE *FileNode, FSP_FILE_DESC *FileDesc, PFILE_OBJECT FileObject) FSP_FILE_NODE *FileNode, FSP_FILE_DESC *FileDesc, PFILE_OBJECT FileObject)
{ {

View File

@ -66,11 +66,10 @@ NTSTATUS DriverEntry(
DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = FspQuerySecurity; DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = FspQuerySecurity;
DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = FspSetSecurity; DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = FspSetSecurity;
/* setup the I/O preparation functions */ /* setup the I/O prepare/complete functions */
FspIopPrepareFunction[IRP_MJ_CREATE] = FspFsvolCreatePrepare; FspIopPrepareFunction[IRP_MJ_CREATE] = FspFsvolCreatePrepare;
/* setup the I/O completion functions */
FspIopCompleteFunction[IRP_MJ_CREATE] = FspFsvolCreateComplete; FspIopCompleteFunction[IRP_MJ_CREATE] = FspFsvolCreateComplete;
FspIopRetryCompleteFunction[IRP_MJ_CREATE] = FspFsvolCreateRetryComplete;
FspIopCompleteFunction[IRP_MJ_CLOSE] = FspFsvolCloseComplete; FspIopCompleteFunction[IRP_MJ_CLOSE] = FspFsvolCloseComplete;
FspIopCompleteFunction[IRP_MJ_READ] = FspFsvolReadComplete; FspIopCompleteFunction[IRP_MJ_READ] = FspFsvolReadComplete;
FspIopCompleteFunction[IRP_MJ_WRITE] = FspFsvolWriteComplete; FspIopCompleteFunction[IRP_MJ_WRITE] = FspFsvolWriteComplete;

View File

@ -225,10 +225,15 @@ _IRQL_requires_max_(APC_LEVEL)
_IRQL_requires_same_ _IRQL_requires_same_
typedef VOID FSP_IOCMPL_DISPATCH( typedef VOID FSP_IOCMPL_DISPATCH(
_Inout_ PIRP Irp, _In_ const FSP_FSCTL_TRANSACT_RSP *Response); _Inout_ PIRP Irp, _In_ const FSP_FSCTL_TRANSACT_RSP *Response);
FSP_IOPREP_DISPATCH FspFsvolCreatePrepare; _IRQL_requires_max_(APC_LEVEL)
_IRQL_requires_same_
typedef NTSTATUS FSP_IORETR_DISPATCH(
_Inout_ PIRP Irp, _Inout_ FSP_FSCTL_TRANSACT_REQ *Request);
FSP_IOCMPL_DISPATCH FspFsvolCleanupComplete; FSP_IOCMPL_DISPATCH FspFsvolCleanupComplete;
FSP_IOCMPL_DISPATCH FspFsvolCloseComplete; FSP_IOCMPL_DISPATCH FspFsvolCloseComplete;
FSP_IOPREP_DISPATCH FspFsvolCreatePrepare;
FSP_IOCMPL_DISPATCH FspFsvolCreateComplete; FSP_IOCMPL_DISPATCH FspFsvolCreateComplete;
FSP_IORETR_DISPATCH FspFsvolCreateRetryComplete;
FSP_IOCMPL_DISPATCH FspFsvolDeviceControlComplete; FSP_IOCMPL_DISPATCH FspFsvolDeviceControlComplete;
FSP_IOCMPL_DISPATCH FspFsvolDirectoryControlComplete; FSP_IOCMPL_DISPATCH FspFsvolDirectoryControlComplete;
FSP_IOCMPL_DISPATCH FspFsvolFileSystemControlComplete; FSP_IOCMPL_DISPATCH FspFsvolFileSystemControlComplete;
@ -385,7 +390,7 @@ BOOLEAN FspIoqPostIrpEx(FSP_IOQ *Ioq, PIRP Irp, BOOLEAN BestEffort, NTSTATUS *PR
PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp, PLARGE_INTEGER Timeout); PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp, PLARGE_INTEGER Timeout);
BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp); BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp);
PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint); PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint);
BOOLEAN FspIoqRetryCompleteIrp(FSP_IOQ *Ioq, PIRP Irp); BOOLEAN FspIoqRetryCompleteIrp(FSP_IOQ *Ioq, PIRP Irp, NTSTATUS *PResult);
PIRP FspIoqNextCompleteIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp); PIRP FspIoqNextCompleteIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp);
/* I/O processing */ /* I/O processing */
@ -418,6 +423,7 @@ VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceDereference);
VOID FspIopCompleteCanceledIrp(PIRP Irp); VOID FspIopCompleteCanceledIrp(PIRP Irp);
NTSTATUS FspIopDispatchPrepare(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request); NTSTATUS FspIopDispatchPrepare(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request);
VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response); VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
NTSTATUS FspIopDispatchRetryComplete(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request);
/* device management */ /* device management */
#define FSP_DEVICE_VOLUME_NAME_LENMAX (FSP_FSCTL_VOLUME_NAME_SIZEMAX - sizeof(WCHAR)) #define FSP_DEVICE_VOLUME_NAME_LENMAX (FSP_FSCTL_VOLUME_NAME_SIZEMAX - sizeof(WCHAR))
@ -654,5 +660,6 @@ extern PDEVICE_OBJECT FspFsctlDiskDeviceObject;
extern PDEVICE_OBJECT FspFsctlNetDeviceObject; extern PDEVICE_OBJECT FspFsctlNetDeviceObject;
extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[]; extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[];
extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[]; extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[];
extern FSP_IORETR_DISPATCH *FspIopRetryCompleteFunction[];
#endif #endif

View File

@ -19,6 +19,7 @@ VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceDereference);
VOID FspIopCompleteCanceledIrp(PIRP Irp); VOID FspIopCompleteCanceledIrp(PIRP Irp);
NTSTATUS FspIopDispatchPrepare(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request); NTSTATUS FspIopDispatchPrepare(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request);
VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response); VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
NTSTATUS FspIopDispatchRetryComplete(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request);
#ifdef ALLOC_PRAGMA #ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FspIopCreateRequestFunnel) #pragma alloc_text(PAGE, FspIopCreateRequestFunnel)
@ -29,6 +30,7 @@ VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
#pragma alloc_text(PAGE, FspIopCompleteCanceledIrp) #pragma alloc_text(PAGE, FspIopCompleteCanceledIrp)
#pragma alloc_text(PAGE, FspIopDispatchPrepare) #pragma alloc_text(PAGE, FspIopDispatchPrepare)
#pragma alloc_text(PAGE, FspIopDispatchComplete) #pragma alloc_text(PAGE, FspIopDispatchComplete)
#pragma alloc_text(PAGE, FspIopDispatchRetryComplete)
#endif #endif
static const LONG Delays[] = static const LONG Delays[] =
@ -268,5 +270,19 @@ VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response)
FspIopCompleteFunction[IrpSp->MajorFunction](Irp, Response); FspIopCompleteFunction[IrpSp->MajorFunction](Irp, Response);
} }
NTSTATUS FspIopDispatchRetryComplete(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request)
{
PAGED_CODE();
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
ASSERT(IRP_MJ_MAXIMUM_FUNCTION >= IrpSp->MajorFunction);
if (0 != FspIopRetryCompleteFunction[IrpSp->MajorFunction])
return FspIopRetryCompleteFunction[IrpSp->MajorFunction](Irp, Request);
else
return STATUS_SUCCESS;
}
FSP_IOPREP_DISPATCH *FspIopPrepareFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; FSP_IOPREP_DISPATCH *FspIopPrepareFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
FSP_IORETR_DISPATCH *FspIopRetryCompleteFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];

View File

@ -518,7 +518,7 @@ PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint)
return FspCsqRemoveNextIrp(&Ioq->ProcessIoCsq, &PeekContext); return FspCsqRemoveNextIrp(&Ioq->ProcessIoCsq, &PeekContext);
} }
BOOLEAN FspIoqRetryCompleteIrp(FSP_IOQ *Ioq, PIRP Irp) BOOLEAN FspIoqRetryCompleteIrp(FSP_IOQ *Ioq, PIRP Irp, NTSTATUS *PResult)
{ {
NTSTATUS Result; NTSTATUS Result;
#if defined(FSP_IOQ_PROCESS_NO_CANCEL) #if defined(FSP_IOQ_PROCESS_NO_CANCEL)
@ -528,7 +528,18 @@ BOOLEAN FspIoqRetryCompleteIrp(FSP_IOQ *Ioq, PIRP Irp)
FspIrpTimestamp(Irp) = QueryInterruptTimeInSec() + Ioq->IrpTimeout; FspIrpTimestamp(Irp) = QueryInterruptTimeInSec() + Ioq->IrpTimeout;
#endif #endif
Result = FspCsqInsertIrpEx(&Ioq->RetriedIoCsq, Irp, 0, 0); Result = FspCsqInsertIrpEx(&Ioq->RetriedIoCsq, Irp, 0, 0);
return NT_SUCCESS(Result); if (NT_SUCCESS(Result))
{
if (0 != PResult)
*PResult = STATUS_PENDING;
return TRUE;
}
else
{
if (0 != PResult)
*PResult = Result;
return FALSE;
}
} }
PIRP FspIoqNextCompleteIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp) PIRP FspIoqNextCompleteIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp)
@ -536,5 +547,5 @@ PIRP FspIoqNextCompleteIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp)
FSP_IOQ_PEEK_CONTEXT PeekContext; FSP_IOQ_PEEK_CONTEXT PeekContext;
PeekContext.IrpHint = 0 != BoundaryIrp ? BoundaryIrp : (PVOID)1; PeekContext.IrpHint = 0 != BoundaryIrp ? BoundaryIrp : (PVOID)1;
PeekContext.ExpirationTime = 0; PeekContext.ExpirationTime = 0;
return IoCsqRemoveNextIrp(&Ioq->RetriedIoCsq, &PeekContext); return FspCsqRemoveNextIrp(&Ioq->RetriedIoCsq, &PeekContext);
} }

View File

@ -517,7 +517,7 @@ NTSTATUS FspVolumeTransact(
PUINT8 BufferEnd; PUINT8 BufferEnd;
FSP_FSCTL_TRANSACT_RSP *Response, *NextResponse; FSP_FSCTL_TRANSACT_RSP *Response, *NextResponse;
FSP_FSCTL_TRANSACT_REQ *Request, *PendingIrpRequest; FSP_FSCTL_TRANSACT_REQ *Request, *PendingIrpRequest;
PIRP ProcessIrp, PendingIrp, RepostedIrp = 0; PIRP ProcessIrp, PendingIrp, RetriedIrp, RepostedIrp;
LARGE_INTEGER Timeout; LARGE_INTEGER Timeout;
/* process any user-mode file system responses */ /* process any user-mode file system responses */
@ -539,6 +539,27 @@ NTSTATUS FspVolumeTransact(
Response = NextResponse; Response = NextResponse;
} }
/* process any retried IRP's */
RepostedIrp = 0;
for (;;)
{
/* get the next retried IRP, but do not go beyond the first reposted IRP! */
RetriedIrp = FspIoqNextCompleteIrp(FsvolDeviceExtension->Ioq, RepostedIrp);
if (0 == RetriedIrp)
break;
Result = FspIopDispatchRetryComplete(RetriedIrp, FspIrpRequest(RetriedIrp));
if (STATUS_PENDING == Result)
{
/*
* The IRP has been reposted to our Ioq. Remember the first such IRP,
* so that we know to break the loop if we see it again.
*/
if (0 == RepostedIrp)
RepostedIrp = RetriedIrp;
}
}
/* were we sent an output buffer? */ /* were we sent an output buffer? */
if (0 == Irp->MdlAddress) if (0 == Irp->MdlAddress)
{ {
@ -564,6 +585,7 @@ NTSTATUS FspVolumeTransact(
} }
/* send any pending IRP's to the user-mode file system */ /* send any pending IRP's to the user-mode file system */
RepostedIrp = 0;
Request = MdlBuffer; Request = MdlBuffer;
BufferEnd = (PUINT8)MdlBuffer + OutputBufferLength; BufferEnd = (PUINT8)MdlBuffer + OutputBufferLength;
ASSERT(FspFsctlTransactCanProduceRequest(Request, BufferEnd)); ASSERT(FspFsctlTransactCanProduceRequest(Request, BufferEnd));