📄 memory.c
字号:
/*
* COPYRIGHT: GNU GENERAL PUBLIC LICENSE VERSION 2
* PROJECT: ReiserFs file system driver for Windows NT/2000/XP/Vista.
* FILE: memory.c
* PURPOSE:
* PROGRAMMER: Mark Piper, Matt Wu, Bo Brant閚.
* HOMEPAGE:
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include "rfsd.h"
/* GLOBALS ***************************************************************/
extern PRFSD_GLOBAL RfsdGlobal;
/* DEFINITIONS *************************************************************/
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, RfsdAllocateIrpContext)
#pragma alloc_text(PAGE, RfsdFreeIrpContext)
#pragma alloc_text(PAGE, RfsdAllocateFcb)
#pragma alloc_text(PAGE, RfsdFreeFcb)
#pragma alloc_text(PAGE, RfsdAllocateMcb)
#pragma alloc_text(PAGE, RfsdSearchMcbTree)
#pragma alloc_text(PAGE, RfsdSearchMcb)
#pragma alloc_text(PAGE, RfsdGetFullFileName)
#pragma alloc_text(PAGE, RfsdRefreshMcb)
#pragma alloc_text(PAGE, RfsdAddMcbNode)
#pragma alloc_text(PAGE, RfsdDeleteMcbNode)
#pragma alloc_text(PAGE, RfsdFreeMcbTree)
#if DISABLED
#pragma alloc_text(PAGE, RfsdCheckBitmapConsistency)
#pragma alloc_text(PAGE, RfsdCheckSetBlock)
#endif
#pragma alloc_text(PAGE, RfsdInitializeVcb)
#pragma alloc_text(PAGE, RfsdFreeCcb)
#pragma alloc_text(PAGE, RfsdAllocateCcb)
#pragma alloc_text(PAGE, RfsdFreeVcb)
#pragma alloc_text(PAGE, RfsdCreateFcbFromMcb)
#pragma alloc_text(PAGE, RfsdSyncUninitializeCacheMap)
#endif
PRFSD_IRP_CONTEXT
RfsdAllocateIrpContext (IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp )
{
PIO_STACK_LOCATION IoStackLocation;
PRFSD_IRP_CONTEXT IrpContext;
ASSERT(DeviceObject != NULL);
ASSERT(Irp != NULL);
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
ExAcquireResourceExclusiveLite(
&RfsdGlobal->LAResource,
TRUE );
IrpContext = (PRFSD_IRP_CONTEXT) (
ExAllocateFromNPagedLookasideList(
&(RfsdGlobal->RfsdIrpContextLookasideList)));
ExReleaseResourceForThreadLite(
&RfsdGlobal->LAResource,
ExGetCurrentResourceThread() );
if (IrpContext == NULL) {
IrpContext = ExAllocatePool( NonPagedPool, sizeof(RFSD_IRP_CONTEXT) );
//
// Zero out the irp context and indicate that it is from pool and
// not region allocated
//
RtlZeroMemory(IrpContext, sizeof(RFSD_IRP_CONTEXT));
SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_FROM_POOL);
} else {
//
// Zero out the irp context and indicate that it is from zone and
// not pool allocated
//
RtlZeroMemory(IrpContext, sizeof(RFSD_IRP_CONTEXT) );
}
if (!IrpContext) {
return NULL;
}
IrpContext->Identifier.Type = RFSDICX;
IrpContext->Identifier.Size = sizeof(RFSD_IRP_CONTEXT);
IrpContext->Irp = Irp;
IrpContext->MajorFunction = IoStackLocation->MajorFunction;
IrpContext->MinorFunction = IoStackLocation->MinorFunction;
IrpContext->DeviceObject = DeviceObject;
IrpContext->FileObject = IoStackLocation->FileObject;
if (IrpContext->FileObject != NULL) {
IrpContext->RealDevice = IrpContext->FileObject->DeviceObject;
} else if (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) {
if (IoStackLocation->Parameters.MountVolume.Vpb) {
IrpContext->RealDevice =
IoStackLocation->Parameters.MountVolume.Vpb->RealDevice;
}
}
if (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL ||
IrpContext->MajorFunction == IRP_MJ_DEVICE_CONTROL ||
IrpContext->MajorFunction == IRP_MJ_SHUTDOWN) {
IrpContext->IsSynchronous = TRUE;
} else if (IrpContext->MajorFunction == IRP_MJ_CLEANUP ||
IrpContext->MajorFunction == IRP_MJ_CLOSE) {
IrpContext->IsSynchronous = FALSE;
}
#if (_WIN32_WINNT >= 0x0500)
else if (IrpContext->MajorFunction == IRP_MJ_PNP) {
if (IoGetCurrentIrpStackLocation(Irp)->FileObject == NULL) {
IrpContext->IsSynchronous = TRUE;
} else {
IrpContext->IsSynchronous = IoIsOperationSynchronous(Irp);
}
}
#endif //(_WIN32_WINNT >= 0x0500)
else {
IrpContext->IsSynchronous = IoIsOperationSynchronous(Irp);
}
#if 0
//
// Temporary workaround for a bug in close that makes it reference a
// fileobject when it is no longer valid.
//
if (IrpContext->MajorFunction == IRP_MJ_CLOSE) {
IrpContext->IsSynchronous = TRUE;
}
#endif
IrpContext->IsTopLevel = (IoGetTopLevelIrp() == Irp);
IrpContext->ExceptionInProgress = FALSE;
return IrpContext;
}
NTSTATUS
RfsdCompleteIrpContext (
IN PRFSD_IRP_CONTEXT IrpContext,
IN NTSTATUS Status )
{
PIRP Irp = NULL;
BOOLEAN bPrint;
Irp = IrpContext->Irp;
if (Irp != NULL) {
if (NT_ERROR(Status)) {
Irp->IoStatus.Information = 0;
}
Irp->IoStatus.Status = Status;
bPrint = !IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);
RfsdCompleteRequest(
Irp, bPrint, (CCHAR)(NT_SUCCESS(Status)?
IO_DISK_INCREMENT : IO_NO_INCREMENT) );
IrpContext->Irp = NULL;
}
RfsdFreeIrpContext(IrpContext);
return Status;
}
VOID
RfsdFreeIrpContext (IN PRFSD_IRP_CONTEXT IrpContext)
{
ASSERT(IrpContext != NULL);
ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
(IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
RfsdUnpinRepinnedBcbs(IrpContext);
// Return the Irp context record to the region or to pool depending on
// its flag
if (FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_FROM_POOL)) {
IrpContext->Identifier.Type = 0;
IrpContext->Identifier.Size = 0;
ExFreePool( IrpContext );
} else {
IrpContext->Identifier.Type = 0;
IrpContext->Identifier.Size = 0;
ExAcquireResourceExclusiveLite(
&RfsdGlobal->LAResource,
TRUE );
ExFreeToNPagedLookasideList(&(RfsdGlobal->RfsdIrpContextLookasideList), IrpContext);
ExReleaseResourceForThreadLite(
&RfsdGlobal->LAResource,
ExGetCurrentResourceThread() );
}
}
VOID
RfsdRepinBcb (
IN PRFSD_IRP_CONTEXT IrpContext,
IN PBCB Bcb
)
{
PRFSD_REPINNED_BCBS Repinned;
Repinned = &IrpContext->Repinned;
return;
#if 0
ULONG i;
while (Repinned) {
for (i = 0; i < RFSD_REPINNED_BCBS_ARRAY_SIZE; i += 1) {
if (Repinned->Bcb[i] == Bcb) {
return;
}
}
Repinned = Repinned->Next;
}
while (TRUE) {
for (i = 0; i < RFSD_REPINNED_BCBS_ARRAY_SIZE; i += 1) {
if (Repinned->Bcb[i] == Bcb) {
return;
}
if (Repinned->Bcb[i] == NULL) {
Repinned->Bcb[i] = Bcb;
CcRepinBcb( Bcb );
return;
}
}
if (Repinned->Next == NULL) {
Repinned->Next = ExAllocatePool( PagedPool, sizeof(RFSD_REPINNED_BCBS) );
RtlZeroMemory( Repinned->Next, sizeof(RFSD_REPINNED_BCBS) );
}
Repinned = Repinned->Next;
}
#endif
}
VOID
RfsdUnpinRepinnedBcbs (
IN PRFSD_IRP_CONTEXT IrpContext
)
{
IO_STATUS_BLOCK RaiseIosb;
PRFSD_REPINNED_BCBS Repinned;
BOOLEAN WriteThroughToDisk;
PFILE_OBJECT FileObject = NULL;
BOOLEAN ForceVerify = FALSE;
ULONG i;
Repinned = &IrpContext->Repinned;
RaiseIosb.Status = STATUS_SUCCESS;
WriteThroughToDisk = (BOOLEAN) (IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH) ||
IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_FLOPPY));
while (Repinned != NULL) {
for (i = 0; i < RFSD_REPINNED_BCBS_ARRAY_SIZE; i += 1) {
if (Repinned->Bcb[i] != NULL) {
IO_STATUS_BLOCK Iosb;
ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
if ( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_FLOPPY) ) {
FileObject = CcGetFileObjectFromBcb( Repinned->Bcb[i] );
}
ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
CcUnpinRepinnedBcb( Repinned->Bcb[i],
WriteThroughToDisk,
&Iosb );
ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
if ( !NT_SUCCESS(Iosb.Status) ) {
if (RaiseIosb.Status == STATUS_SUCCESS) {
RaiseIosb = Iosb;
}
if (FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_FLOPPY) &&
(IrpContext->MajorFunction != IRP_MJ_CLEANUP) &&
(IrpContext->MajorFunction != IRP_MJ_FLUSH_BUFFERS) &&
(IrpContext->MajorFunction != IRP_MJ_SET_INFORMATION)) {
CcPurgeCacheSection( FileObject->SectionObjectPointer,
NULL,
0,
FALSE );
ForceVerify = TRUE;
}
}
Repinned->Bcb[i] = NULL;
} else {
break;
}
}
if (Repinned != &IrpContext->Repinned)
{
PRFSD_REPINNED_BCBS Saved;
Saved = Repinned->Next;
ExFreePool( Repinned );
Repinned = Saved;
} else {
Repinned = Repinned->Next;
IrpContext->Repinned.Next = NULL;
}
}
if (!NT_SUCCESS(RaiseIosb.Status)) {
DbgBreak();
if (ForceVerify && FileObject) {
SetFlag(FileObject->DeviceObject->Flags, DO_VERIFY_VOLUME);
IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
FileObject->DeviceObject );
}
IrpContext->Irp->IoStatus = RaiseIosb;
RfsdNormalizeAndRaiseStatus(IrpContext, RaiseIosb.Status );
}
return;
}
PRFSD_FCB
RfsdAllocateFcb (IN PRFSD_VCB Vcb,
IN PRFSD_MCB RfsdMcb,
IN PRFSD_INODE Inode )
{
PRFSD_FCB Fcb;
ExAcquireResourceExclusiveLite(
&RfsdGlobal->LAResource,
TRUE );
Fcb = (PRFSD_FCB) ExAllocateFromNPagedLookasideList(
&(RfsdGlobal->RfsdFcbLookasideList));
ExReleaseResourceForThreadLite(
&RfsdGlobal->LAResource,
ExGetCurrentResourceThread() );
if (Fcb == NULL) {
Fcb = (PRFSD_FCB)ExAllocatePool(NonPagedPool, sizeof(RFSD_FCB));
RtlZeroMemory(Fcb, sizeof(RFSD_FCB));
SetFlag(Fcb->Flags, FCB_FROM_POOL);
} else {
RtlZeroMemory(Fcb, sizeof(RFSD_FCB));
}
if (!Fcb) {
return NULL;
}
Fcb->Identifier.Type = RFSDFCB;
Fcb->Identifier.Size = sizeof(RFSD_FCB);
FsRtlInitializeFileLock (
&Fcb->FileLockAnchor,
NULL,
NULL );
Fcb->OpenHandleCount = 0;
Fcb->ReferenceCount = 0;
Fcb->Vcb = Vcb;
#if DBG
Fcb->AnsiFileName.MaximumLength = (USHORT)
RfsdUnicodeToOEMSize(&(RfsdMcb->ShortName)) + 1;
Fcb->AnsiFileName.Buffer = (PUCHAR)
ExAllocatePool(PagedPool, Fcb->AnsiFileName.MaximumLength);
if (!Fcb->AnsiFileName.Buffer) {
goto errorout;
}
RtlZeroMemory(Fcb->AnsiFileName.Buffer, Fcb->AnsiFileName.MaximumLength);
RfsdUnicodeToOEM( &(Fcb->AnsiFileName),
&(RfsdMcb->ShortName));
#endif
RfsdMcb->FileAttr = FILE_ATTRIBUTE_NORMAL;
if (S_ISDIR(Inode->i_mode)) {
SetFlag(RfsdMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY);
}
if ( IsFlagOn(Vcb->Flags, VCB_READ_ONLY) ||
RfsdIsReadOnly(Inode->i_mode)) {
SetFlag(RfsdMcb->FileAttr, FILE_ATTRIBUTE_READONLY);
}
Fcb->Inode = Inode;
Fcb->RfsdMcb = RfsdMcb;
RfsdMcb->RfsdFcb = Fcb;
RtlZeroMemory(&Fcb->Header, sizeof(FSRTL_COMMON_FCB_HEADER));
Fcb->Header.NodeTypeCode = (USHORT) RFSDFCB;
Fcb->Header.NodeByteSize = sizeof(RFSD_FCB);
Fcb->Header.IsFastIoPossible = FastIoIsNotPossible;
Fcb->Header.Resource = &(Fcb->MainResource);
Fcb->Header.PagingIoResource = &(Fcb->PagingIoResource);
// NOTE: In EXT2, the low part was stored in i_size (a 32-bit value); the high part would be stored in the acl field...
// However, on ReiserFS, the i_size is a 64-bit value.
Fcb->Header.FileSize.QuadPart = Fcb->Inode->i_size;
Fcb->Header.AllocationSize.QuadPart =
CEILING_ALIGNED(Fcb->Header.FileSize.QuadPart, (ULONGLONG)Vcb->BlockSize);
Fcb->Header.ValidDataLength.QuadPart = (LONGLONG)(0x7fffffffffffffff);
Fcb->SectionObject.DataSectionObject = NULL;
Fcb->SectionObject.SharedCacheMap = NULL;
Fcb->SectionObject.ImageSectionObject = NULL;
ExInitializeResourceLite(&(Fcb->MainResource));
ExInitializeResourceLite(&(Fcb->PagingIoResource));
InsertTailList(&Vcb->FcbList, &Fcb->Next);
#if DBG
ExAcquireResourceExclusiveLite(
&RfsdGlobal->CountResource,
TRUE );
RfsdGlobal->FcbAllocated++;
ExReleaseResourceForThreadLite(
&RfsdGlobal->CountResource,
ExGetCurrentResourceThread() );
#endif
return Fcb;
#if DBG
errorout:
#endif
if (Fcb) {
#if DBG
if (Fcb->AnsiFileName.Buffer)
ExFreePool(Fcb->AnsiFileName.Buffer);
#endif
if (FlagOn(Fcb->Flags, FCB_FROM_POOL)) {
ExFreePool( Fcb );
} else {
ExAcquireResourceExclusiveLite(
&RfsdGlobal->LAResource,
TRUE );
ExFreeToNPagedLookasideList(&(RfsdGlobal->RfsdFcbLookasideList), Fcb);
ExReleaseResourceForThreadLite(
&RfsdGlobal->LAResource,
ExGetCurrentResourceThread() );
}
}
return NULL;
}
VOID
RfsdFreeFcb (IN PRFSD_FCB Fcb)
{
PRFSD_VCB Vcb;
ASSERT(Fcb != NULL);
ASSERT((Fcb->Identifier.Type == RFSDFCB) &&
(Fcb->Identifier.Size == sizeof(RFSD_FCB)));
Vcb = Fcb->Vcb;
FsRtlUninitializeFileLock(&Fcb->FileLockAnchor);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -