NTSTATUS Ext2WriteComplete (IN PEXT2_IRP_CONTEXT IrpContext) { NTSTATUS Status = STATUS_UNSUCCESSFUL; PFILE_OBJECT FileObject; PIRP Irp; PIO_STACK_LOCATION IrpSp; __try { ASSERT(IrpContext); ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT))); FileObject = IrpContext->FileObject; Irp = IrpContext->Irp; IrpSp = IoGetCurrentIrpStackLocation(Irp); CcMdlWriteComplete(FileObject, &(IrpSp->Parameters.Write.ByteOffset), Irp->MdlAddress); Irp->MdlAddress = NULL; Status = STATUS_SUCCESS; } __finally { if (!IrpContext->ExceptionInProgress) { Ext2CompleteIrpContext(IrpContext, Status); } } return Status; }
NTSTATUS NtfsCompleteMdl ( IN PIRP_CONTEXT IrpContext, IN PIRP Irp ) /*++ Routine Description: This routine performs the function of completing Mdl read and write requests. It should be called only from NtfsFsdRead and NtfsFsdWrite. Arguments: Irp - Supplies the originating Irp. Return Value: NTSTATUS - Will always be STATUS_PENDING or STATUS_SUCCESS. --*/ { PFILE_OBJECT FileObject; PIO_STACK_LOCATION IrpSp; PNTFS_ADVANCED_FCB_HEADER Header; ASSERT( FlagOn( IrpContext->TopLevelIrpContext->State, IRP_CONTEXT_STATE_OWNS_TOP_LEVEL )); PAGED_CODE(); DebugTrace( +1, Dbg, ("NtfsCompleteMdl\n") ); DebugTrace( 0, Dbg, ("IrpContext = %08lx\n", IrpContext) ); DebugTrace( 0, Dbg, ("Irp = %08lx\n", Irp) ); // // Do completion processing. // FileObject = IoGetCurrentIrpStackLocation( Irp )->FileObject; switch( IrpContext->MajorFunction ) { case IRP_MJ_READ: CcMdlReadComplete( FileObject, Irp->MdlAddress ); break; case IRP_MJ_WRITE: try { PSCB Scb; VBO StartingVbo; LONGLONG ByteCount; LONGLONG ByteRange; BOOLEAN DoingIoAtEof = FALSE; ASSERT( FlagOn( IrpContext->State, IRP_CONTEXT_STATE_WAIT )); IrpSp = IoGetCurrentIrpStackLocation( Irp ); Scb = (PSCB)(IrpSp->FileObject->FsContext); Header = &(Scb->Header); // // Now synchronize with the FsRtl Header and Scb. // if (Header->PagingIoResource != NULL) { StartingVbo = IrpSp->Parameters.Write.ByteOffset.QuadPart; ByteCount = (LONGLONG) IrpSp->Parameters.Write.Length; ByteRange = StartingVbo + ByteCount + PAGE_SIZE - 1; ClearFlag( ((ULONG) ByteRange), PAGE_SIZE - 1 ); ExAcquireResourceSharedLite( Header->PagingIoResource, TRUE ); NtfsAcquireFsrtlHeader( Scb ); // // Now see if this is at EOF. // Recursive flush will generate IO which ends on page boundary // which is why we rounded the range // if (ByteRange > Header->ValidDataLength.QuadPart) { // // Mark that we are writing to EOF. If someone else is currently // writing to EOF, wait for them. // ASSERT( ByteRange - StartingVbo < MAXULONG ); DoingIoAtEof = !FlagOn( Header->Flags, FSRTL_FLAG_EOF_ADVANCE_ACTIVE ) || NtfsWaitForIoAtEof( Header, (PLARGE_INTEGER)&StartingVbo, (ULONG)(ByteRange - StartingVbo) ); if (DoingIoAtEof) { SetFlag( Header->Flags, FSRTL_FLAG_EOF_ADVANCE_ACTIVE ); #if (DBG || defined( NTFS_FREE_ASSERTS )) ((PSCB) Header)->IoAtEofThread = (PERESOURCE_THREAD) ExGetCurrentResourceThread(); #endif // // Store this in the IrpContext until commit or post. // IrpContext->CleanupStructure = Scb; } } NtfsReleaseFsrtlHeader( Scb ); } CcMdlWriteComplete( FileObject, &IrpSp->Parameters.Write.ByteOffset, Irp->MdlAddress ); } finally { if (Header->PagingIoResource != NULL) { ExReleaseResourceLite( Header->PagingIoResource ); } } break; default: DebugTrace( DEBUG_TRACE_ERROR, 0, ("Illegal Mdl Complete.\n") ); ASSERTMSG("Illegal Mdl Complete, About to bugcheck ", FALSE); NtfsBugCheck( IrpContext->MajorFunction, 0, 0 ); } // // Mdl is now deallocated. // Irp->MdlAddress = NULL; // // Ignore errors. CC has already cleaned up his structures. // IrpContext->ExceptionStatus = STATUS_SUCCESS; NtfsMinimumExceptionProcessing( IrpContext ); // // Complete the request and exit right away. // NtfsCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); DebugTrace( -1, Dbg, ("NtfsCompleteMdl -> STATUS_SUCCESS\n") ); return STATUS_SUCCESS; }