diff --git a/src/sys/read.c b/src/sys/read.c index 8ab70706..1c42edc8 100644 --- a/src/sys/read.c +++ b/src/sys/read.c @@ -139,6 +139,10 @@ static NTSTATUS FspFsvolReadCached( } } + /* + * From this point forward we must jump to the CLEANUP label on failure. + */ + /* are we using the copy or MDL interface? */ if (!FlagOn(IrpSp->MinorFunction, IRP_MN_MDL)) { @@ -148,22 +152,14 @@ static NTSTATUS FspFsvolReadCached( Irp->UserBuffer : MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); if (0 == Buffer) { - FspFileNodeRelease(FileNode, Main); - return STATUS_INSUFFICIENT_RESOURCES; + Result = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; } Result = FspCcCopyRead(FileObject, &ReadOffset, ReadLength, CanWait, Buffer, &Irp->IoStatus); - if (!NT_SUCCESS(Result)) - { - FspFileNodeRelease(FileNode, Main); - return Result; - } - if (STATUS_PENDING == Result) - { - FspFileNodeRelease(FileNode, Main); - return FspWqRepostIrpWorkItem(Irp, FspFsvolReadCached, 0); - } + if (!NT_SUCCESS(Result) || STATUS_PENDING == Result) + goto cleanup; } else { @@ -172,10 +168,8 @@ static NTSTATUS FspFsvolReadCached( Result = FspCcMdlRead(FileObject, &ReadOffset, ReadLength, &Irp->MdlAddress, &Irp->IoStatus); if (!NT_SUCCESS(Result)) - { - FspFileNodeRelease(FileNode, Main); - return Result; - } + goto cleanup; + ASSERT(STATUS_PENDING != Result); } /* update the current file offset if synchronous I/O */ @@ -185,6 +179,14 @@ static NTSTATUS FspFsvolReadCached( FspFileNodeRelease(FileNode, Main); return STATUS_SUCCESS; + +cleanup: + FspFileNodeRelease(FileNode, Main); + + if (STATUS_PENDING == Result) + return FspWqRepostIrpWorkItem(Irp, FspFsvolReadCached, 0); + + return Result; } static NTSTATUS FspFsvolReadNonCached( diff --git a/src/sys/write.c b/src/sys/write.c index 986fc4ef..52747da5 100644 --- a/src/sys/write.c +++ b/src/sys/write.c @@ -106,6 +106,7 @@ static NTSTATUS FspFsvolWriteCached( BOOLEAN SynchronousIo = BooleanFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO); FSP_FSCTL_FILE_INFO FileInfo; CC_FILE_SIZES FileSizes; + UINT64 OriginalFileSize; UINT64 WriteEndOffset; BOOLEAN ExtendingFile; BOOLEAN Success; @@ -136,6 +137,7 @@ static NTSTATUS FspFsvolWriteCached( ASSERT(FspTimeoutInfinity32 == FspFsvolDeviceExtension(FsvolDeviceObject)->VolumeParams.FileInfoTimeout); FspFileNodeGetFileInfo(FileNode, &FileInfo); + OriginalFileSize = FileInfo.FileSize; WriteEndOffset = WriteToEndOfFile ? FileInfo.FileSize + WriteLength : WriteOffset.QuadPart + WriteLength; ExtendingFile = FileInfo.FileSize < WriteEndOffset; @@ -183,6 +185,10 @@ static NTSTATUS FspFsvolWriteCached( } } + /* + * From this point forward we must jump to the CLEANUP label on failure. + */ + /* are we using the copy or MDL interface? */ if (!FlagOn(IrpSp->MinorFunction, IRP_MN_MDL)) { @@ -192,21 +198,13 @@ static NTSTATUS FspFsvolWriteCached( Irp->UserBuffer : MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); if (0 == Buffer) { - FspFileNodeRelease(FileNode, Main); - return STATUS_INSUFFICIENT_RESOURCES; + Result = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; } Result = FspCcCopyWrite(FileObject, &WriteOffset, WriteLength, CanWait, Buffer); - if (!NT_SUCCESS(Result)) - { - FspFileNodeRelease(FileNode, Main); - return Result; - } - if (STATUS_PENDING == Result) - { - FspFileNodeRelease(FileNode, Main); - return FspWqRepostIrpWorkItem(Irp, FspFsvolWriteCached, 0); - } + if (!NT_SUCCESS(Result) || STATUS_PENDING == Result) + goto cleanup; Irp->IoStatus.Information = WriteLength; } @@ -217,10 +215,8 @@ static NTSTATUS FspFsvolWriteCached( Result = FspCcPrepareMdlWrite(FileObject, &WriteOffset, WriteLength, &Irp->MdlAddress, &Irp->IoStatus); if (!NT_SUCCESS(Result)) - { - FspFileNodeRelease(FileNode, Main); - return Result; - } + goto cleanup; + ASSERT(STATUS_PENDING != Result); } /* update the current file offset if synchronous I/O */ @@ -233,6 +229,16 @@ static NTSTATUS FspFsvolWriteCached( FspFileNodeRelease(FileNode, Main); return STATUS_SUCCESS; + +cleanup: + CcGetFileSizePointer(FileObject)->QuadPart = OriginalFileSize; + + FspFileNodeRelease(FileNode, Main); + + if (STATUS_PENDING == Result) + return FspWqRepostIrpWorkItem(Irp, FspFsvolWriteCached, 0); + + return Result; } static VOID FspFsvolWriteCachedDeferred(PVOID Context1, PVOID Context2)