{
NTSTATUS RC = STATUS_SUCCESS;
PIO_STACK_LOCATION PtrIoStackLocation = NULL;
PFILE_OBJECT PtrFileObject = NULL;
PtrExt2FCB PtrFCB = NULL;
PtrExt2CCB PtrCCB = NULL;
PtrExt2VCB PtrVCB = NULL;
PtrExt2NTRequiredFCB PtrReqdFCB = NULL;
BOOLEAN AcquiredFCB = FALSE;
BOOLEAN PostRequest = FALSE;
BOOLEAN CanWait = TRUE;
try {
// First, get a pointer to the current I/O stack location
PtrIoStackLocation = IoGetCurrentIrpStackLocation(PtrIrp);
ASSERT(PtrIoStackLocation);
PtrFileObject = PtrIoStackLocation->FileObject;
ASSERT(PtrFileObject);
// Get the FCB and CCB pointers
PtrCCB = (PtrExt2CCB)(PtrFileObject->FsContext2);
ASSERT(PtrCCB);
PtrFCB = PtrCCB->PtrFCB;
AssertFCB( PtrFCB );
/*ASSERT(PtrFCB); ASSERT(PtrFCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_FCB );*/
PtrReqdFCB = &(PtrFCB->NTRequiredFCB);
// Get some of the parameters supplied to us
CanWait = ((PtrIrpContext->IrpContextFlags & EXT2_IRP_CONTEXT_CAN_BLOCK) ? TRUE : FALSE);
// If we cannot wait, post the request immediately since a flush is inherently blocking/synchronous.if (!CanWait) {
PostRequest = TRUE;
try_return();
}
// Check the type of object passed-in. That will determine the course of// action we take.if ((PtrFCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_VCB) || (PtrFCB->FCBFlags & EXT2_FCB_ROOT_DIRECTORY)) {
if (PtrFCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_VCB) {
PtrVCB = (PtrExt2VCB)(PtrFCB);
} else {
PtrVCB = PtrFCB->PtrVCB;
}
// The caller wishes to flush all files for the mounted// logical volume. The flush volume routine below should simply// walk through all of the open file streams, acquire the// FCB resource, and request the flush operation from the Cache// Manager. Basically, the sequence of operations listed below// for a single file should be executed on all open files.Ext2FlushLogicalVolume(PtrIrpContext, PtrIrp, PtrVCB);
try_return();
}
if (!(PtrFCB->FCBFlags & EXT2_FCB_DIRECTORY))
{
// This is a regular file.ExAcquireResourceExclusiveLite(&(PtrReqdFCB->MainResource), TRUE);
AcquiredFCB = TRUE;
// Request the Cache Manager to perform a flush operation.// Further, instruct the Cache Manager that we wish to flush the// entire file stream.Ext2FlushAFile(PtrReqdFCB, &(PtrIrp->IoStatus));
RC = PtrIrp->IoStatus.Status;
// All done. You may want to also flush the directory entry for the// file stream at this time.// Some log-based FSD implementations may wish to flush their// log files at this time. Finally, you should update the time-stamp// values for the file stream appropriately. This would involve// obtaining the current time and modifying the appropriate directory// entry fields.
}
try_exit:
if (AcquiredFCB)
{
Ext2ReleaseResource(&(PtrReqdFCB->MainResource));
DebugTrace(DEBUG_TRACE_MISC, "*** FCB Released [Flush]", 0);
DebugTraceState( "FCBMain AC:0x%LX SW:0x%LX EX:0x%LX [Flush]",
PtrReqdFCB->MainResource.ActiveCount,
PtrReqdFCB->MainResource.NumberOfExclusiveWaiters,
PtrReqdFCB->MainResource.NumberOfSharedWaiters );
AcquiredFCB = FALSE;
}
if (!PostRequest)
{
PIO_STACK_LOCATION PtrNextIoStackLocation = NULL;
NTSTATUS RC1 = STATUS_SUCCESS;
// Send the request down at this point.// To do this, you must set the next IRP stack location, and// maybe set a completion routine.// Be careful about marking the IRP pending if the lower level// driver returned pending and you do have a completion routine!
PtrNextIoStackLocation = IoGetNextIrpStackLocation(PtrIrp);
*PtrNextIoStackLocation = *PtrIoStackLocation;
// Set the completion routine to "eat-up" any// STATUS_INVALID_DEVICE_REQUEST error code returned by the lower// level driver.IoSetCompletionRoutine(PtrIrp, Ext2FlushCompletion, NULL, TRUE, TRUE, TRUE);
/* * The exception handlers propably masked out the * fact that PtrVCB was never set. * -- Filip Navara, 18/08/2004 */
PtrVCB = PtrFCB->PtrVCB;
RC1 = IoCallDriver(PtrVCB->TargetDeviceObject, PtrIrp);
RC = ((RC1 == STATUS_INVALID_DEVICE_REQUEST) ? RC : RC1);
}
} finally {
if (PostRequest) {
// Nothing to lock now.
RC = Ext2PostRequest(PtrIrpContext, PtrIrp);
} else {
// Release the IRP context at this time.Ext2ReleaseIrpContext(PtrIrpContext);
}
}
return(RC);
}
Generated on Sun May 27 2012 05:23:43 for ReactOS by
1.7.6.1
ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.