From acf1b453fc4bc8d244ddfc620c3beac5bfac6921 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Wed, 27 Jan 2016 13:41:37 -0800 Subject: [PATCH] sys: FspIopRetryCompleteIrp() and related changes --- src/sys/create.c | 71 +++++++++++++++--------------------------------- src/sys/driver.c | 1 - src/sys/driver.h | 13 ++------- src/sys/iop.c | 56 ++++++++++++++++++++++++++++---------- src/sys/ioq.c | 4 +++ src/sys/volume.c | 3 +- 6 files changed, 71 insertions(+), 77 deletions(-) diff --git a/src/sys/create.c b/src/sys/create.c index e2c97eb3..3b2f807d 100644 --- a/src/sys/create.c +++ b/src/sys/create.c @@ -14,10 +14,9 @@ static NTSTATUS FspFsvolCreate( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); FSP_IOPREP_DISPATCH FspFsvolCreatePrepare; FSP_IOCMPL_DISPATCH FspFsvolCreateComplete; -FSP_IORETR_DISPATCH FspFsvolCreateRetryComplete; -static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, +static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response, FSP_FILE_NODE *FileNode, FSP_FILE_DESC *FileDesc, PFILE_OBJECT FileObject, - BOOLEAN FlushImage, BOOLEAN Retrying); + BOOLEAN FlushImage); static VOID FspFsvolCreatePostClose(FSP_FILE_DESC *FileDesc); static FSP_IOP_REQUEST_FINI FspFsvolCreateRequestFini; static FSP_IOP_REQUEST_FINI FspFsvolCreateTryOpenRequestFini; @@ -30,7 +29,6 @@ FSP_DRIVER_DISPATCH FspCreate; #pragma alloc_text(PAGE, FspFsvolCreate) #pragma alloc_text(PAGE, FspFsvolCreatePrepare) #pragma alloc_text(PAGE, FspFsvolCreateComplete) -#pragma alloc_text(PAGE, FspFsvolCreateRetryComplete) #pragma alloc_text(PAGE, FspFsvolCreateTryOpen) #pragma alloc_text(PAGE, FspFsvolCreatePostClose) #pragma alloc_text(PAGE, FspFsvolCreateRequestFini) @@ -532,7 +530,6 @@ NTSTATUS FspFsvolCreateComplete( FileNode->IsDirectory = BooleanFlagOn(Response->Rsp.Create.Opened.FileInfo.FileAttributes, FILE_ATTRIBUTE_DIRECTORY); FileDesc->UserContext2 = Response->Rsp.Create.Opened.UserContext2; - FileDesc->State.FileInfo = Response->Rsp.Create.Opened.FileInfo; DeleteOnClose = BooleanFlagOn(IrpSp->Parameters.Create.Options, FILE_DELETE_ON_CLOSE); @@ -580,7 +577,7 @@ NTSTATUS FspFsvolCreateComplete( (FlagOn(Response->Rsp.Create.Opened.GrantedAccess, FILE_WRITE_DATA) || DeleteOnClose); - Result = FspFsvolCreateTryOpen(Irp, FileNode, FileDesc, FileObject, FlushImage, FALSE); + Result = FspFsvolCreateTryOpen(Irp, Response, FileNode, FileDesc, FileObject, FlushImage); } else if (FILE_SUPERSEDED == Response->IoStatus.Information || @@ -632,7 +629,7 @@ NTSTATUS FspFsvolCreateComplete( else { /* SUCCESS! */ - FspFileNodeSetFileInfo(FileNode, &FileDesc->State.FileInfo); + FspFileNodeSetFileInfo(FileNode, &Response->Rsp.Create.Opened.FileInfo); FspIopRequestContext(Request, RequestFileDesc) = 0; Irp->IoStatus.Information = (ULONG_PTR)Response->IoStatus.Information; Result = STATUS_SUCCESS; @@ -666,6 +663,16 @@ NTSTATUS FspFsvolCreateComplete( Irp->IoStatus.Information = Request->Req.Overwrite.Supersede ? FILE_SUPERSEDED : FILE_OVERWRITTEN; Result = STATUS_SUCCESS; } + else if (FspFsctlTransactReservedKind == Request->Kind) + { + /* + * A Reserved request is a special request used when retrying a file open. + */ + + BOOLEAN FlushImage = 0 != FspIopRequestContext(Request, RequestState); + + Result = FspFsvolCreateTryOpen(Irp, Response, FileNode, FileDesc, FileObject, FlushImage); + } else ASSERT(0); @@ -674,77 +681,43 @@ NTSTATUS FspFsvolCreateComplete( IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName); } -NTSTATUS FspFsvolCreateRetryComplete( - PIRP Irp) -{ - PAGED_CODE(); - - NTSTATUS Result; - FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); - FSP_FILE_NODE *FileNode; - FSP_FILE_DESC *FileDesc; - PFILE_OBJECT FileObject; - BOOLEAN FlushImage; - - ASSERT(FspFsctlTransactCreateKind == Request->Kind); - - FileDesc = FspIopRequestContext(Request, RequestFileDesc); - FileNode = FileDesc->FileNode; - FileObject = FspIopRequestContext(Request, RequestFileObject); - FlushImage = 0 != FspIopRequestContext(Request, RequestState); - - Result = FspFsvolCreateTryOpen(Irp, FileNode, FileDesc, FileObject, FlushImage, TRUE); - if (STATUS_PENDING == Result) - return Result; - else - { - DEBUGLOGIRP(Irp, Result); - - FspIopCompleteIrp(Irp, Result); - return STATUS_SUCCESS; - } -} - -static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, +static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response, FSP_FILE_NODE *FileNode, FSP_FILE_DESC *FileDesc, PFILE_OBJECT FileObject, - BOOLEAN FlushImage, BOOLEAN Retrying) + BOOLEAN FlushImage) { PAGED_CODE(); FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); BOOLEAN Success; - ASSERT(FspFsctlTransactCreateKind == Request->Kind); - Success = FspFileNodeTryAcquireExclusive(FileNode, Both); if (!Success) { /* repost the IRP to retry later */ NTSTATUS Result; - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); - FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = - FspFsvolDeviceExtension(IrpSp->DeviceObject); - if (!Retrying) + if (FspFsctlTransactCreateKind == Request->Kind) { /* disassociate the FileDesc momentarily from the Request */ Request = FspIrpRequest(Irp); FspIopRequestContext(Request, RequestFileDesc) = 0; /* reset the Request and reassociate the FileDesc and FileObject with it */ + Request->Kind = FspFsctlTransactReservedKind; FspIopResetRequest(Request, FspFsvolCreateTryOpenRequestFini); FspIopRequestContext(Request, RequestFileDesc) = FileDesc; FspIopRequestContext(Request, RequestFileObject) = FileObject; FspIopRequestContext(Request, RequestState) = (PVOID)(UINT_PTR)FlushImage; } - FspIoqRetryCompleteIrp(FsvolDeviceExtension->Ioq, Irp, &Result); + FspIopRetryCompleteIrp(Irp, Response, &Result); return Result; } FspFileObjectSetSizes(FileObject, - FileDesc->State.FileInfo.AllocationSize, FileDesc->State.FileInfo.FileSize); + Response->Rsp.Create.Opened.FileInfo.AllocationSize, + Response->Rsp.Create.Opened.FileInfo.FileSize); if (FlushImage) { @@ -769,7 +742,7 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, FspFileNodeRelease(FileNode, Both); /* SUCCESS! */ - FspFileNodeSetFileInfo(FileNode, &FileDesc->State.FileInfo); + FspFileNodeSetFileInfo(FileNode, &Response->Rsp.Create.Opened.FileInfo); FspIopRequestContext(Request, RequestFileDesc) = 0; Irp->IoStatus.Information = FILE_OPENED; return STATUS_SUCCESS; diff --git a/src/sys/driver.c b/src/sys/driver.c index 2b94c4f5..e465798d 100644 --- a/src/sys/driver.c +++ b/src/sys/driver.c @@ -69,7 +69,6 @@ NTSTATUS DriverEntry( /* setup the I/O prepare/complete functions */ FspIopPrepareFunction[IRP_MJ_CREATE] = FspFsvolCreatePrepare; FspIopCompleteFunction[IRP_MJ_CREATE] = FspFsvolCreateComplete; - FspIopRetryCompleteFunction[IRP_MJ_CREATE] = FspFsvolCreateRetryComplete; FspIopCompleteFunction[IRP_MJ_CLOSE] = FspFsvolCloseComplete; FspIopCompleteFunction[IRP_MJ_READ] = FspFsvolReadComplete; FspIopCompleteFunction[IRP_MJ_WRITE] = FspFsvolWriteComplete; diff --git a/src/sys/driver.h b/src/sys/driver.h index 55fdeb4a..84319e82 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -225,15 +225,10 @@ _IRQL_requires_max_(APC_LEVEL) _IRQL_requires_same_ typedef NTSTATUS FSP_IOCMPL_DISPATCH( _Inout_ PIRP Irp, _In_ const FSP_FSCTL_TRANSACT_RSP *Response); -_IRQL_requires_max_(APC_LEVEL) -_IRQL_requires_same_ -typedef NTSTATUS FSP_IORETR_DISPATCH( - _Inout_ PIRP Irp); FSP_IOCMPL_DISPATCH FspFsvolCleanupComplete; FSP_IOCMPL_DISPATCH FspFsvolCloseComplete; FSP_IOPREP_DISPATCH FspFsvolCreatePrepare; FSP_IOCMPL_DISPATCH FspFsvolCreateComplete; -FSP_IORETR_DISPATCH FspFsvolCreateRetryComplete; FSP_IOCMPL_DISPATCH FspFsvolDeviceControlComplete; FSP_IOCMPL_DISPATCH FspFsvolDirectoryControlComplete; FSP_IOCMPL_DISPATCH FspFsvolFileSystemControlComplete; @@ -422,9 +417,10 @@ NTSTATUS FspIopPostWorkRequestFunnel(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_TRANSACT_REQ *Request, BOOLEAN BestEffort); VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceDereference); VOID FspIopCompleteCanceledIrp(PIRP Irp); +BOOLEAN FspIopRetryCompleteIrp(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response, NTSTATUS *PResult); +FSP_FSCTL_TRANSACT_RSP *FspIopIrpResponse(PIRP Irp); NTSTATUS FspIopDispatchPrepare(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request); NTSTATUS FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response); -NTSTATUS FspIopDispatchRetryComplete(PIRP Irp); /* device management */ #define FSP_DEVICE_VOLUME_NAME_LENMAX (FSP_FSCTL_VOLUME_NAME_SIZEMAX - sizeof(WCHAR)) @@ -590,10 +586,6 @@ typedef struct { FSP_FILE_NODE *FileNode; UINT64 UserContext2; - union - { - FSP_FSCTL_FILE_INFO FileInfo; /* create time only */ - } State; } FSP_FILE_DESC; NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject, ULONG ExtraSize, FSP_FILE_NODE **PFileNode); @@ -663,6 +655,5 @@ extern PDEVICE_OBJECT FspFsctlDiskDeviceObject; extern PDEVICE_OBJECT FspFsctlNetDeviceObject; extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[]; extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[]; -extern FSP_IORETR_DISPATCH *FspIopRetryCompleteFunction[]; #endif diff --git a/src/sys/iop.c b/src/sys/iop.c index c5bcfa3a..83d3aef9 100644 --- a/src/sys/iop.c +++ b/src/sys/iop.c @@ -18,9 +18,10 @@ NTSTATUS FspIopPostWorkRequestFunnel(PDEVICE_OBJECT DeviceObject, static IO_COMPLETION_ROUTINE FspIopPostWorkRequestCompletion; VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceDereference); VOID FspIopCompleteCanceledIrp(PIRP Irp); +BOOLEAN FspIopRetryCompleteIrp(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response, NTSTATUS *PResult); +FSP_FSCTL_TRANSACT_RSP *FspIopIrpResponse(PIRP Irp); NTSTATUS FspIopDispatchPrepare(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request); NTSTATUS FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response); -NTSTATUS FspIopDispatchRetryComplete(PIRP Irp); #ifdef ALLOC_PRAGMA #pragma alloc_text(PAGE, FspIopCreateRequestFunnel) @@ -30,9 +31,10 @@ NTSTATUS FspIopDispatchRetryComplete(PIRP Irp); #pragma alloc_text(PAGE, FspIopPostWorkRequestFunnel) #pragma alloc_text(PAGE, FspIopCompleteIrpEx) #pragma alloc_text(PAGE, FspIopCompleteCanceledIrp) +#pragma alloc_text(PAGE, FspIopRetryCompleteIrp) +#pragma alloc_text(PAGE, FspIopIrpResponse) #pragma alloc_text(PAGE, FspIopDispatchPrepare) #pragma alloc_text(PAGE, FspIopDispatchComplete) -#pragma alloc_text(PAGE, FspIopDispatchRetryComplete) #endif static const LONG Delays[] = @@ -81,6 +83,7 @@ typedef struct { FSP_IOP_REQUEST_FINI *RequestFini; PVOID Context[3]; + FSP_FSCTL_TRANSACT_RSP *Response; __declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) UINT8 RequestBuf[]; } FSP_FSCTL_TRANSACT_REQ_HEADER; @@ -142,6 +145,9 @@ VOID FspIopDeleteRequest(FSP_FSCTL_TRANSACT_REQ *Request) if (0 != RequestHeader->RequestFini) RequestHeader->RequestFini(RequestHeader->Context); + if (0 != RequestHeader->Response) + FspFree(RequestHeader->Response); + FspFree(RequestHeader); } @@ -260,6 +266,39 @@ VOID FspIopCompleteCanceledIrp(PIRP Irp) FspIopCompleteIrpEx(Irp, STATUS_CANCELLED, TRUE); } +BOOLEAN FspIopRetryCompleteIrp(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response, NTSTATUS *PResult) +{ + PAGED_CODE(); + + PDEVICE_OBJECT DeviceObject = IoGetCurrentIrpStackLocation(Irp)->DeviceObject; + FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); + FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); + FSP_FSCTL_TRANSACT_REQ_HEADER *RequestHeader = (PVOID)((PUINT8)Request - sizeof *RequestHeader); + + ASSERT(0 != Request); + + if (0 != Response && RequestHeader->Response != Response) + { + if (0 != RequestHeader->Response) + FspFree(RequestHeader->Response); + RequestHeader->Response = FspAllocMustSucceed(Response->Size); + RtlCopyMemory(RequestHeader->Response, Response, Response->Size); + Response = RequestHeader->Response; + } + + return FspIoqRetryCompleteIrp(FsvolDeviceExtension->Ioq, Irp, PResult); +} + +FSP_FSCTL_TRANSACT_RSP *FspIopIrpResponse(PIRP Irp) +{ + PAGED_CODE(); + + FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); + FSP_FSCTL_TRANSACT_REQ_HEADER *RequestHeader = (PVOID)((PUINT8)Request - sizeof *RequestHeader); + + return RequestHeader->Response; +} + NTSTATUS FspIopDispatchPrepare(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request) { PAGED_CODE(); @@ -285,18 +324,5 @@ NTSTATUS FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response return FspIopCompleteFunction[IrpSp->MajorFunction](Irp, Response); } -NTSTATUS FspIopDispatchRetryComplete(PIRP Irp) -{ - PAGED_CODE(); - - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); - - ASSERT(IRP_MJ_MAXIMUM_FUNCTION >= IrpSp->MajorFunction); - ASSERT(0 != FspIopRetryCompleteFunction[IrpSp->MajorFunction]); - - return FspIopRetryCompleteFunction[IrpSp->MajorFunction](Irp); -} - FSP_IOPREP_DISPATCH *FspIopPrepareFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; -FSP_IORETR_DISPATCH *FspIopRetryCompleteFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; diff --git a/src/sys/ioq.c b/src/sys/ioq.c index fc209b15..37b931d1 100644 --- a/src/sys/ioq.c +++ b/src/sys/ioq.c @@ -329,7 +329,11 @@ static PIRP FspIoqRetriedPeekNextIrp(PIO_CSQ IoCsq, PIRP Irp, PVOID PeekContext) } } else + { + if (Irp == IrpHint) + return 0; return Irp; + } } _IRQL_raises_(DISPATCH_LEVEL) diff --git a/src/sys/volume.c b/src/sys/volume.c index b25b86d5..6977a808 100644 --- a/src/sys/volume.c +++ b/src/sys/volume.c @@ -548,7 +548,8 @@ NTSTATUS FspVolumeTransact( if (0 == RetriedIrp) break; - Result = FspIopDispatchRetryComplete(RetriedIrp); + Response = FspIopIrpResponse(RetriedIrp); + Result = FspIopDispatchComplete(RetriedIrp, Response); if (STATUS_PENDING == Result) { /*