301 lines
7.1 KiB
C
301 lines
7.1 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1989 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
Flush.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module implements the File Flush buffers routine for Rx called by the
|
|||
|
dispatch driver.
|
|||
|
|
|||
|
In a future version of the wrapper, it may be that flush will be routed thru lowio.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Joe Linn [JoeLinn] 15-dec-1994
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "precomp.h"
|
|||
|
#pragma hdrstop
|
|||
|
|
|||
|
//
|
|||
|
// The local debug trace level
|
|||
|
//
|
|||
|
|
|||
|
#define Dbg (DEBUG_TRACE_FLUSH)
|
|||
|
|
|||
|
//RXSTATUS
|
|||
|
//RxLowIoFlushShell (
|
|||
|
// IN PRX_CONTEXT RxContext
|
|||
|
// );
|
|||
|
//
|
|||
|
//RXSTATUS
|
|||
|
//RxLowIoFlushShellCompletion (
|
|||
|
// IN PRX_CONTEXT RxContext
|
|||
|
// );
|
|||
|
|
|||
|
#ifdef ALLOC_PRAGMA
|
|||
|
#pragma alloc_text(PAGE, RxCommonFlushBuffers)
|
|||
|
#pragma alloc_text(PAGE, RxFlushFile)
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
RxCommonFlushBuffers ( RXCOMMON_SIGNATURE )
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This is the common routine for flushing file buffers.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Irp - Supplies the Irp to process
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RXSTATUS - The return status for the operation
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
NTSTATUS Status;
|
|||
|
RxCaptureRequestPacket;
|
|||
|
RxCaptureFcb; RxCaptureFobx; RxCaptureParamBlock; RxCaptureFileObject;
|
|||
|
NODE_TYPE_CODE TypeOfOpen = NodeType(capFcb);
|
|||
|
|
|||
|
PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
|
|||
|
|
|||
|
|
|||
|
BOOLEAN FcbAcquired = FALSE;
|
|||
|
|
|||
|
PAGED_CODE();
|
|||
|
|
|||
|
RxDbgTrace(+1, Dbg, ("RxCommonFlush...IrpC %08lx, Fobx %08lx, Fcb %08lx\n",
|
|||
|
RxContext, capFobx, capFcb));
|
|||
|
RxLog(("%s %lx %lx %lx\n","slF",RxContext,capFcb,capFobx));
|
|||
|
|
|||
|
//
|
|||
|
// CcFlushCache is always synchronous, so if we can't wait enqueue
|
|||
|
// the irp to the Fsp.
|
|||
|
|
|||
|
if ( !FlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT) ) {
|
|||
|
|
|||
|
Status = RxFsdPostRequest( RxContext );
|
|||
|
|
|||
|
RxDbgTrace(-1, Dbg, ("RxCommonFlushBuffers -> %08lx\n", Status ));
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
Status = STATUS_SUCCESS;
|
|||
|
|
|||
|
try {
|
|||
|
|
|||
|
//
|
|||
|
// Case on the type of open that we are trying to flush
|
|||
|
//
|
|||
|
|
|||
|
switch (TypeOfOpen) {
|
|||
|
|
|||
|
case RDBSS_NTC_STORAGE_TYPE_FILE:
|
|||
|
|
|||
|
RxDbgTrace(0, Dbg, ("Flush User File Open\n", 0));
|
|||
|
|
|||
|
Status = RxAcquireExclusiveFcb( RxContext, capFcb );
|
|||
|
|
|||
|
if (Status != STATUS_SUCCESS) break;
|
|||
|
|
|||
|
FcbAcquired = TRUE;
|
|||
|
|
|||
|
//
|
|||
|
// If the file is cached then flush its cache
|
|||
|
//
|
|||
|
|
|||
|
Status = RxFlushFile( RxContext, capFcb );
|
|||
|
|
|||
|
if (!NT_SUCCESS( Status )) break;
|
|||
|
|
|||
|
//rdrs don't do this.....only local FSs
|
|||
|
////
|
|||
|
//// Check if we should be changing the time or file size
|
|||
|
//
|
|||
|
//RxAdjustFileTimesAndSize(RXCOMMON_ARGUMENTS);
|
|||
|
|
|||
|
// if we make this lowio.........
|
|||
|
////
|
|||
|
//// Initialize LowIO_CONTEXT block in the RxContext and Calldown
|
|||
|
//
|
|||
|
//RxInitializeLowIoContext(LowIoContext,LOWIO_OP_FLUSH);
|
|||
|
//
|
|||
|
//Status = RxLowIoFlushShell(RxContext);
|
|||
|
|
|||
|
MINIRDR_CALL(Status,RxContext,capFcb->MRxDispatch,MRxFlush,(RxContext));
|
|||
|
break;
|
|||
|
|
|||
|
case RDBSS_NTC_SPOOLFILE:
|
|||
|
|
|||
|
RxDbgTrace(0, Dbg, ("Flush Sppol File\n", 0));
|
|||
|
|
|||
|
Status = RxAcquireExclusiveFcb( RxContext, capFcb );
|
|||
|
|
|||
|
if (Status != STATUS_SUCCESS) break;
|
|||
|
|
|||
|
FcbAcquired = TRUE;
|
|||
|
|
|||
|
// should this be low io???
|
|||
|
////
|
|||
|
//// Initialize LowIO_CONTEXT block in the RxContext and Calldown
|
|||
|
//
|
|||
|
//RxInitializeLowIoContext(LowIoContext,LOWIO_OP_FLUSH);
|
|||
|
//
|
|||
|
//Status = RxLowIoFlushShell(RxContext);
|
|||
|
|
|||
|
MINIRDR_CALL(Status,RxContext,capFcb->MRxDispatch,MRxFlush,(RxContext));
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
Status = STATUS_INVALID_DEVICE_REQUEST;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
} finally {
|
|||
|
|
|||
|
DebugUnwind( RxCommonFlushBuffers );
|
|||
|
|
|||
|
if (FcbAcquired) { RxReleaseFcb( RxContext, capFcb ); }
|
|||
|
|
|||
|
//
|
|||
|
// If this is a normal termination then pass the request on
|
|||
|
// to the target device object.
|
|||
|
//
|
|||
|
|
|||
|
if (!AbnormalTermination()) {
|
|||
|
|
|||
|
NOTHING;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
RxDbgTrace(-1, Dbg, ("RxCommonFlushBuffers -> %08lx\n", Status));
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#if 0
|
|||
|
BUGBUG
|
|||
|
THIS CODE WOULD BE USED IF THIS IS CHANGED TO LOWIO
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
RxLowIoFlushShellCompletion (
|
|||
|
IN PRX_CONTEXT RxContext
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
these completion shells are pretty similar. BUT as the error handling gets more
|
|||
|
robust the routines will become increasingly dissimilar. for flush, everything is synchronous...that's
|
|||
|
a difference with read/write/lock; we keep the same declarations and format for later when we decide to roll up the
|
|||
|
common part of these routines.
|
|||
|
|
|||
|
This routine postprocesses a flush request after it comes back from the
|
|||
|
minirdr. It is the complement of LowIoFlushShell.
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
RxContext - the usual
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
whatever value supplied by the caller or STATUS_MORE_PROCESSING_REQUIRED.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
NTSTATUS Status;
|
|||
|
RxCaptureRequestPacket;
|
|||
|
RxCaptureFcb; RxCaptureFobx; RxCaptureParamBlock;
|
|||
|
PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
|
|||
|
BOOLEAN SynchronousIo = !BooleanFlagOn(RxContext->Flags,RX_CONTEXT_FLAG_ASYNC_OPERATION);
|
|||
|
BOOLEAN PagingIo = BooleanFlagOn(capReqPacket->Flags, IRP_PAGING_IO);
|
|||
|
ERESOURCE_THREAD ThisResourceThreadId;
|
|||
|
|
|||
|
|
|||
|
Status = RxContext->StoredStatus;
|
|||
|
RxDbgTrace(+1, Dbg, ("RxLowIoFlushShellCompletion entry Status = %08lx\n", Status));
|
|||
|
RxLog(("FlshShlComp %x\n",RxContext));
|
|||
|
|
|||
|
//switch (Status) {
|
|||
|
//case STATUS_SUCCESS:
|
|||
|
// break;
|
|||
|
//case STATUS_CONNECTION_INVALID:
|
|||
|
// //joejoe here is where the failover will happen
|
|||
|
// //first we give the local guy current minirdr another chance...then we go
|
|||
|
// //to fullscale retry
|
|||
|
// //return(RxStatus(DISCONNECTED)); //special....let LowIo get us back
|
|||
|
// break;
|
|||
|
//}
|
|||
|
|
|||
|
capReqPacket->IoStatus.Status = Status;
|
|||
|
|
|||
|
RxDbgTrace(-1, Dbg, ("RxLowIoFlushShellCompletion exit Status = %08lx\n", Status));
|
|||
|
return(Status);
|
|||
|
//NOTE THAT THE ASYNC COMPLETION TAIL IS MISSING
|
|||
|
}
|
|||
|
|
|||
|
#define RxSdwFlush(RXCONTEXT) {NOTHING;}
|
|||
|
}
|
|||
|
NTSTATUS
|
|||
|
RxLowIoFlushShell (
|
|||
|
IN PRX_CONTEXT RxContext
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine preprocesses a Flush request before it goes down to the minirdr. It does callouts
|
|||
|
to handle compression, buffering and shadowing. It is the opposite number of LowIoFlushShellCompletion.
|
|||
|
By the time we get here, we are going to the wire.
|
|||
|
Flush buffering was already tried in the UncachedFlush strategy
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
RxContext - the usual
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
whatever value is returned by a callout....or by LowIo.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
NTSTATUS Status;
|
|||
|
RxCaptureFcb; RxCaptureFobx; RxCaptureParamBlock;
|
|||
|
PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
|
|||
|
|
|||
|
RxDbgTrace(+1, Dbg, ("RxLowIoFlushShell entry %08lx\n", 0));
|
|||
|
RxLog(("FlshShl in%x\n",RxContext));
|
|||
|
if (FlagOn(Fcb->FcbState, FCB_STATE_FILE_IS_SHADOWED)) {
|
|||
|
RxSdwFlush(RxContext);
|
|||
|
}
|
|||
|
|
|||
|
Status = RxLowIoSubmit(RxContext,RxLowIoFlushShellCompletion);
|
|||
|
RxDbgTrace(-1, Dbg, ("RxLowIoFlushShell exit Status = %08lx\n", Status));
|
|||
|
return(Status);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|