📄 cachesup.c
字号:
return STATUS_SUCCESS;
}
VOID
UdfMapMetadataView (
IN PIRP_CONTEXT IrpContext,
IN PMAPPED_PVIEW View,
IN PVCB Vcb,
IN USHORT Partition,
IN ULONG Lbn,
IN ULONG Length
)
/*++
Routine Description:
Perform the common work of mapping an extent of metadata into a mapped view.
Arguments:
View - View structure to map the bytes into
Vcb - Vcb of the volume the extent is on
Partition - Partition of the extent
Lbn - Lbn of the extent
Length - Length of the extent
Return Value:
None.
--*/
{
LARGE_INTEGER Offset;
ULONG Vsn;
ASSERT_IRP_CONTEXT( IrpContext );
//
// Remove any existing mapping
//
UdfUnpinView( IrpContext, View );
//
// Update the view information.
//
View->Partition = Partition;
View->Lbn = Lbn;
View->Length = Length;
//
// Find the mapping of this extent in the Metadata stream.
//
Vsn = UdfLookupMetaVsnOfExtent( IrpContext,
Vcb,
Partition,
Lbn,
Length,
FALSE );
Offset.QuadPart = LlBytesFromSectors( Vcb, Vsn );
//
// Map the extent
//
CcMapData( Vcb->MetadataFcb->FileObject,
&Offset,
Length,
TRUE,
&View->Bcb,
&View->View );
}
NTSTATUS
UdfPurgeVolume (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN BOOLEAN DismountUnderway
)
/*++
Routine Description:
This routine is called to purge the volume. The purpose is to make all the stale file
objects in the system go away, minimizing the reference counts, so that the volume may
be locked or deleted.
The Vcb is already acquired exclusively. We will lock out all file operations by
acquiring the global file resource. Then we will walk through all of the Fcb's and
perform the purge.
Arguments:
Vcb - Vcb for the volume to purge.
DismountUnderway - Indicates that we are trying to delete all of the objects.
We will purge the Metadata and VolumeDasd and dereference all internal streams.
Return Value:
NTSTATUS - The first failure of the purge operation.
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
PVOID RestartKey = NULL;
PFCB ThisFcb = NULL;
PFCB NextFcb;
BOOLEAN RemovedFcb;
PAGED_CODE();
//
// Force any remaining Fcb's in the delayed close queue to be closed.
//
UdfFspClose( Vcb );
//
// Acquire the global file resource.
//
UdfAcquireAllFiles( IrpContext, Vcb );
//
// Loop through each Fcb in the Fcb Table and perform the flush.
//
while (TRUE) {
//
// Lock the Vcb to lookup the next Fcb.
//
UdfLockVcb( IrpContext, Vcb );
NextFcb = UdfGetNextFcb( IrpContext, Vcb, &RestartKey );
//
// Reference the NextFcb if present.
//
if (NextFcb != NULL) {
NextFcb->FcbReference += 1;
}
//
// If the last Fcb is present then decrement reference count and call teardown
// to see if it should be removed.
//
if (ThisFcb != NULL) {
ThisFcb->FcbReference -= 1;
UdfUnlockVcb( IrpContext, Vcb );
UdfTeardownStructures( IrpContext, ThisFcb, FALSE, &RemovedFcb );
} else {
UdfUnlockVcb( IrpContext, Vcb );
}
//
// Break out of the loop if no more Fcb's.
//
if (NextFcb == NULL) {
break;
}
//
// Move to the next Fcb.
//
ThisFcb = NextFcb;
//
// If there is a image section then see if that can be closed.
//
if (ThisFcb->FcbNonpaged->SegmentObject.ImageSectionObject != NULL) {
MmFlushImageSection( &ThisFcb->FcbNonpaged->SegmentObject, MmFlushForWrite );
}
//
// If there is a data section then purge this. If there is an image
// section then we won't be able to. Remember this if it is our first
// error.
//
if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) &&
!CcPurgeCacheSection( &ThisFcb->FcbNonpaged->SegmentObject,
NULL,
0,
FALSE ) &&
(Status == STATUS_SUCCESS)) {
Status = STATUS_UNABLE_TO_DELETE_SECTION;
}
//
// Dereference the internal stream if dismounting.
//
if (DismountUnderway &&
(SafeNodeType( ThisFcb ) != UDFS_NTC_FCB_DATA) &&
(ThisFcb->FileObject != NULL)) {
UdfDeleteInternalStream( IrpContext, ThisFcb );
}
}
//
// Now look at the Root Index, Metadata, Volume Dasd and VAT Fcbs.
// Note that we usually hit the Root Index in the loop above, but
// it is possible miss it if it didn't get into the Fcb table in the
// first place!
//
if (DismountUnderway) {
if (Vcb->RootIndexFcb != NULL) {
ThisFcb = Vcb->RootIndexFcb;
InterlockedIncrement( &ThisFcb->FcbReference );
if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) &&
!CcPurgeCacheSection( &ThisFcb->FcbNonpaged->SegmentObject,
NULL,
0,
FALSE ) &&
(Status == STATUS_SUCCESS)) {
Status = STATUS_UNABLE_TO_DELETE_SECTION;
}
UdfDeleteInternalStream( IrpContext, ThisFcb );
InterlockedDecrement( &ThisFcb->FcbReference );
UdfTeardownStructures( IrpContext, ThisFcb, FALSE, &RemovedFcb );
}
if (Vcb->MetadataFcb != NULL) {
ThisFcb = Vcb->MetadataFcb;
InterlockedIncrement( &ThisFcb->FcbReference );
if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) &&
!CcPurgeCacheSection( &ThisFcb->FcbNonpaged->SegmentObject,
NULL,
0,
FALSE ) &&
(Status == STATUS_SUCCESS)) {
Status = STATUS_UNABLE_TO_DELETE_SECTION;
}
UdfDeleteInternalStream( IrpContext, ThisFcb );
InterlockedDecrement( &ThisFcb->FcbReference );
UdfTeardownStructures( IrpContext, ThisFcb, FALSE, &RemovedFcb );
}
if (Vcb->VatFcb != NULL) {
ThisFcb = Vcb->VatFcb;
InterlockedIncrement( &ThisFcb->FcbReference );
if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) &&
!CcPurgeCacheSection( &ThisFcb->FcbNonpaged->SegmentObject,
NULL,
0,
FALSE ) &&
(Status == STATUS_SUCCESS)) {
Status = STATUS_UNABLE_TO_DELETE_SECTION;
}
UdfDeleteInternalStream( IrpContext, ThisFcb );
InterlockedDecrement( &ThisFcb->FcbReference );
UdfTeardownStructures( IrpContext, ThisFcb, FALSE, &RemovedFcb );
}
if (Vcb->VolumeDasdFcb != NULL) {
ThisFcb = Vcb->VolumeDasdFcb;
InterlockedIncrement( &ThisFcb->FcbReference );
if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) &&
!CcPurgeCacheSection( &ThisFcb->FcbNonpaged->SegmentObject,
NULL,
0,
FALSE ) &&
(Status == STATUS_SUCCESS)) {
Status = STATUS_UNABLE_TO_DELETE_SECTION;
}
InterlockedDecrement( &ThisFcb->FcbReference );
UdfTeardownStructures( IrpContext, ThisFcb, FALSE, &RemovedFcb );
}
}
//
// Release all of the files.
//
UdfReleaseAllFiles( IrpContext, Vcb );
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -