📄 memory.c
字号:
RfsdCheckSetBlock(PRFSD_IRP_CONTEXT IrpContext, PRFSD_VCB Vcb, ULONG Block)
{
DbgBreak();
ULONG Group, dwBlk, Length;
RTL_BITMAP BlockBitmap;
PVOID BitmapCache;
PBCB BitmapBcb;
LARGE_INTEGER Offset;
BOOLEAN bModified = FALSE;
Group = (Block - RFSD_FIRST_DATA_BLOCK) / BLOCKS_PER_GROUP;
dwBlk = (Block - RFSD_FIRST_DATA_BLOCK) % BLOCKS_PER_GROUP;
Offset.QuadPart = (LONGLONG) Vcb->BlockSize;
Offset.QuadPart = Offset.QuadPart * Vcb->GroupDesc[Group].bg_block_bitmap;
if (Group == Vcb->NumOfGroups - 1) {
Length = TOTAL_BLOCKS % BLOCKS_PER_GROUP;
/* s_blocks_count is integer multiple of s_blocks_per_group */
if (Length == 0)
Length = BLOCKS_PER_GROUP;
} else {
Length = BLOCKS_PER_GROUP;
}
if (dwBlk >= Length)
return FALSE;
if (!CcPinRead( Vcb->StreamObj,
&Offset,
Vcb->BlockSize,
PIN_WAIT,
&BitmapBcb,
&BitmapCache ) ) {
RfsdPrint((DBG_ERROR, "RfsdDeleteBlock: PinReading error ...\n"));
return FALSE;
}
RtlInitializeBitMap( &BlockBitmap,
BitmapCache,
Length );
if (RtlCheckBit(&BlockBitmap, dwBlk) == 0) {
DbgBreak();
RtlSetBits(&BlockBitmap, dwBlk, 1);
bModified = TRUE;
}
if (bModified) {
CcSetDirtyPinnedData(BitmapBcb, NULL );
RfsdRepinBcb(IrpContext, BitmapBcb);
RfsdAddMcbEntry(Vcb, Offset.QuadPart, (LONGLONG)Vcb->BlockSize);
}
{
CcUnpinData(BitmapBcb);
BitmapBcb = NULL;
BitmapCache = NULL;
RtlZeroMemory(&BlockBitmap, sizeof(RTL_BITMAP));
}
return (!bModified);
}
#endif
#if DISABLED
BOOLEAN
RfsdCheckBitmapConsistency(PRFSD_IRP_CONTEXT IrpContext, PRFSD_VCB Vcb)
{
DbgBreak();
ULONG i, j, InodeBlocks;
for (i = 0; i < Vcb->NumOfGroups; i++) {
RfsdCheckSetBlock(IrpContext, Vcb, Vcb->GroupDesc[i].bg_block_bitmap);
RfsdCheckSetBlock(IrpContext, Vcb, Vcb->GroupDesc[i].bg_inode_bitmap);
if (i == Vcb->NumOfGroups - 1) {
InodeBlocks = ((INODES_COUNT % INODES_PER_GROUP) *
sizeof(RFSD_INODE) + Vcb->BlockSize - 1) /
(Vcb->BlockSize);
} else {
InodeBlocks = (INODES_PER_GROUP * sizeof(RFSD_INODE) + Vcb->BlockSize - 1) / (Vcb->BlockSize);
}
for (j = 0; j < InodeBlocks; j++ )
RfsdCheckSetBlock(IrpContext, Vcb, Vcb->GroupDesc[i].bg_inode_table + j);
}
return TRUE;
}
#endif
VOID
RfsdInsertVcb(PRFSD_VCB Vcb)
{
InsertTailList(&(RfsdGlobal->VcbList), &Vcb->Next);
}
VOID
RfsdRemoveVcb(PRFSD_VCB Vcb)
{
RemoveEntryList(&Vcb->Next);
}
NTSTATUS
RfsdInitializeVcb( IN PRFSD_IRP_CONTEXT IrpContext,
IN PRFSD_VCB Vcb,
IN PRFSD_SUPER_BLOCK RfsdSb,
IN PDEVICE_OBJECT TargetDevice,
IN PDEVICE_OBJECT VolumeDevice,
IN PVPB Vpb )
{
BOOLEAN VcbResourceInitialized = FALSE;
USHORT VolumeLabelLength;
ULONG IoctlSize;
BOOLEAN NotifySyncInitialized = FALSE;
LONGLONG DiskSize;
LONGLONG PartSize;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
UNICODE_STRING RootNode;
USHORT Buffer[2];
ULONG ChangeCount;
char s_volume_name[16] = "ReiserFS\0"; /* volume name */ // FUTURE: pull in from v2 superblock, if available
int templen;
__try {
if (!Vpb) {
Status = STATUS_DEVICE_NOT_READY;
__leave;
}
RfsdPrint((DBG_ERROR, "RfsdInitializeVcb: Flink = %xh McbList = %xh\n",
Vcb->McbList.Flink, &(Vcb->McbList.Flink)));
#if RFSD_READ_ONLY
SetFlag(Vcb->Flags, VCB_READ_ONLY);
#endif //READ_ONLY
if (IsFlagOn(Vpb->RealDevice->Characteristics, FILE_REMOVABLE_MEDIA)) {
SetFlag(Vcb->Flags, VCB_REMOVABLE_MEDIA);
}
if (IsFlagOn(Vpb->RealDevice->Characteristics, FILE_FLOPPY_DISKETTE)) {
SetFlag(Vcb->Flags, VCB_FLOPPY_DISK);
}
/*if (IsFlagOn(RfsdGlobal->Flags, RFSD_SUPPORT_WRITING)) {
if ((IsFlagOn(RfsdSb->s_feature_incompat, EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) ||
IsFlagOn(RfsdSb->s_feature_incompat, EXT3_FEATURE_INCOMPAT_RECOVER) ||
IsFlagOn(RfsdSb->s_feature_compat, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) ) {
if(IsFlagOn(RfsdGlobal->Flags, EXT3_FORCE_WRITING)) {
ClearFlag(Vcb->Flags, VCB_READ_ONLY);
} else {
SetFlag(Vcb->Flags, VCB_READ_ONLY);
}
} else {
ClearFlag(Vcb->Flags, VCB_READ_ONLY);
}
} else {
SetFlag(Vcb->Flags, VCB_READ_ONLY);
}*/
// RFSD will be read only.
SetFlag(Vcb->Flags, VCB_READ_ONLY);
ExInitializeResourceLite(&Vcb->MainResource);
ExInitializeResourceLite(&Vcb->PagingIoResource);
ExInitializeResourceLite(&Vcb->McbResource);
VcbResourceInitialized = TRUE;
Vcb->Vpb = Vpb;
Vcb->RealDevice = Vpb->RealDevice;
Vpb->DeviceObject = VolumeDevice;
{
UNICODE_STRING LabelName;
OEM_STRING OemName;
LabelName.MaximumLength = 16 * 2;
LabelName.Length = 0;
LabelName.Buffer = Vcb->Vpb->VolumeLabel;
RtlZeroMemory(LabelName.Buffer, LabelName.MaximumLength);
VolumeLabelLength = 16;
while( (VolumeLabelLength > 0) &&
((s_volume_name[VolumeLabelLength-1] == '\0') ||
(s_volume_name[VolumeLabelLength-1] == ' ')) ) {
VolumeLabelLength--;
}
OemName.Buffer = s_volume_name;
OemName.MaximumLength = 16;
OemName.Length = VolumeLabelLength;
templen = RtlOemStringToUnicodeSize(&OemName);
Status = RfsdOEMToUnicode( &LabelName,
&OemName );
if (!NT_SUCCESS(Status)) {
__leave;
}
Vpb->VolumeLabelLength = LabelName.Length;
}
#if DISABLED
Vpb->SerialNumber = ((ULONG*)RfsdSb->s_uuid)[0] + ((ULONG*)RfsdSb->s_uuid)[1] +
((ULONG*)RfsdSb->s_uuid)[2] + ((ULONG*)RfsdSb->s_uuid)[3];
#endif
Vcb->StreamObj = IoCreateStreamFileObject( NULL, Vcb->Vpb->RealDevice);
if (Vcb->StreamObj) {
Vcb->StreamObj->SectionObjectPointer = &(Vcb->SectionObject);
Vcb->StreamObj->Vpb = Vcb->Vpb;
Vcb->StreamObj->ReadAccess = TRUE;
if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
{
Vcb->StreamObj->WriteAccess = TRUE;
Vcb->StreamObj->DeleteAccess = TRUE;
}
else
{
Vcb->StreamObj->WriteAccess = TRUE;
Vcb->StreamObj->DeleteAccess = TRUE;
}
Vcb->StreamObj->FsContext = (PVOID) Vcb;
Vcb->StreamObj->FsContext2 = NULL;
Vcb->StreamObj->Vpb = Vcb->Vpb;
SetFlag(Vcb->StreamObj->Flags, FO_NO_INTERMEDIATE_BUFFERING);
} else {
__leave;
}
InitializeListHead(&Vcb->FcbList);
InitializeListHead(&Vcb->NotifyList);
FsRtlNotifyInitializeSync(&Vcb->NotifySync);
NotifySyncInitialized = TRUE;
Vcb->DeviceObject = VolumeDevice;
Vcb->TargetDeviceObject = TargetDevice;
Vcb->OpenFileHandleCount = 0;
Vcb->ReferenceCount = 0;
Vcb->SuperBlock = RfsdSb;
Vcb->Header.NodeTypeCode = (USHORT) RFSDVCB;
Vcb->Header.NodeByteSize = sizeof(RFSD_VCB);
Vcb->Header.IsFastIoPossible = FastIoIsNotPossible;
Vcb->Header.Resource = &(Vcb->MainResource);
Vcb->Header.PagingIoResource = &(Vcb->PagingIoResource);
Vcb->Vpb->SerialNumber = 'MATT';
DiskSize =
Vcb->DiskGeometry.Cylinders.QuadPart *
Vcb->DiskGeometry.TracksPerCylinder *
Vcb->DiskGeometry.SectorsPerTrack *
Vcb->DiskGeometry.BytesPerSector;
IoctlSize = sizeof(PARTITION_INFORMATION);
Status = RfsdDiskIoControl(
TargetDevice,
IOCTL_DISK_GET_PARTITION_INFO,
NULL,
0,
&Vcb->PartitionInformation,
&IoctlSize );
PartSize = Vcb->PartitionInformation.PartitionLength.QuadPart;
if (!NT_SUCCESS(Status)) {
Vcb->PartitionInformation.StartingOffset.QuadPart = 0;
Vcb->PartitionInformation.PartitionLength.QuadPart =
DiskSize;
PartSize = DiskSize;
Status = STATUS_SUCCESS;
}
IoctlSize = sizeof(ULONG);
Status = RfsdDiskIoControl(
TargetDevice,
IOCTL_DISK_CHECK_VERIFY,
NULL,
0,
&ChangeCount,
&IoctlSize );
if (!NT_SUCCESS(Status)) {
__leave;
}
Vcb->ChangeCount = ChangeCount;
Vcb->Header.AllocationSize.QuadPart =
Vcb->Header.FileSize.QuadPart = PartSize;
Vcb->Header.ValidDataLength.QuadPart =
(LONGLONG)(0x7fffffffffffffff);
/*
Vcb->Header.AllocationSize.QuadPart = (LONGLONG)(rfsd_super_block->s_blocks_count - rfsd_super_block->s_free_blocks_count)
* (RFSD_MIN_BLOCK << rfsd_super_block->s_log_block_size);
Vcb->Header.FileSize.QuadPart = Vcb->Header.AllocationSize.QuadPart;
Vcb->Header.ValidDataLength.QuadPart = Vcb->Header.AllocationSize.QuadPart;
*/
{
CC_FILE_SIZES FileSizes;
FileSizes.AllocationSize.QuadPart =
FileSizes.FileSize.QuadPart =
Vcb->Header.AllocationSize.QuadPart;
FileSizes.ValidDataLength.QuadPart= (LONGLONG)(0x7fffffffffffffff);
CcInitializeCacheMap( Vcb->StreamObj,
&FileSizes,
TRUE,
&(RfsdGlobal->CacheManagerNoOpCallbacks),
Vcb );
}
#if DISABLED // IN FFFS TOO
if (!RfsdLoadGroup(Vcb)) {
Status = STATUS_UNSUCCESSFUL;
__leave;
}
#endif
FsRtlInitializeLargeMcb(&(Vcb->DirtyMcbs), PagedPool);
InitializeListHead(&(Vcb->McbList));
//
// Now allocating the mcb for root ...
//
Buffer[0] = L'\\';
Buffer[1] = 0;
RootNode.Buffer = Buffer;
RootNode.MaximumLength = RootNode.Length = 2;
Vcb->McbTree = RfsdAllocateMcb( Vcb, &RootNode,
FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_NORMAL);
if (!Vcb->McbTree) {
__leave;
}
// Set the root of the filesystem to the root directory's inode / stat data structure
Vcb->McbTree->Key.k_dir_id = RFSD_ROOT_PARENT_ID;
Vcb->McbTree->Key.k_objectid = RFSD_ROOT_OBJECT_ID;
Vcb->McbTree->Key.k_offset = 0;
Vcb->McbTree->Key.k_type = RFSD_KEY_TYPE_v1_STAT_DATA;
#ifdef DISABLED
if (IsFlagOn(RfsdGlobal->Flags, RFSD_CHECKING_BITMAP)) {
RfsdCheckBitmapConsistency(IrpContext, Vcb);
}
{
ULONG dwData[RFSD_BLOCK_TYPES] = {RFSD_NDIR_BLOCKS, 1, 1, 1};
ULONG dwMeta[RFSD_BLOCK_TYPES] = {0, 0, 0, 0};
ULONG i;
KdPrint(("Reminder: " __FUNCTION__ ", dwData, dwMeta??\n"));
for (i = 0; i < RFSD_BLOCK_TYPES; i++) {
dwData[i] = dwData[i] << ((BLOCK_BITS - 2) * i);
if (i > 0) {
dwMeta[i] = 1 + (dwMeta[i - 1] << (BLOCK_BITS - 2));
}
Vcb->dwData[i] = dwData[i];
Vcb->dwMeta[i] = dwMeta[i];
}
}
#endif
SetFlag(Vcb->Flags, VCB_INITIALIZED);
} __finally {
if (!NT_SUCCESS(Status)) {
if (NotifySyncInitialized) {
FsRtlNotifyUninitializeSync(&Vcb->NotifySync);
}
if (Vcb->GroupDesc) {
ExFreePool(Vcb->GroupDesc);
// CcUnpinData(Vcb->GroupDescBcb);
Vcb->GroupDesc = NULL;
}
if (Vcb->SuperBlock) {
ExFreePool(Vcb->SuperBlock);
Vcb->SuperBlock = NULL;
}
if (VcbResourceInitialized) {
ExDeleteResourceLite(&Vcb->MainResource);
ExDeleteResourceLite(&Vcb->PagingIoResource);
}
}
}
return Status;
}
VOID
RfsdFreeVcb (IN PRFSD_VCB Vcb )
{
ASSERT(Vcb != NULL);
ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
(Vcb->Identifier.Size == sizeof(RFSD_VCB)));
FsRtlNotifyUninitializeSync(&Vcb->NotifySync);
if (Vcb->StreamObj) {
if (IsFlagOn(Vcb->StreamObj->Flags, FO_FILE_MODIFIED)) {
IO_STATUS_BLOCK IoStatus;
CcFlushCache(&(Vcb->SectionObject), NULL, 0, &IoStatus);
ClearFlag(Vcb->StreamObj->Flags, FO_FILE_MODIFIED);
}
if (Vcb->StreamObj->PrivateCacheMap)
RfsdSyncUninitializeCacheMap(Vcb->StreamObj);
ObDereferenceObject(Vcb->StreamObj);
Vcb->StreamObj = NULL;
}
#if DBG
if (FsRtlNumberOfRunsInLargeMcb(&(Vcb->DirtyMcbs)) != 0) {
LONGLONG DirtyVba;
LONGLONG DirtyLba;
LONGLONG DirtyLength;
int i;
for (i = 0; FsRtlGetNextLargeMcbEntry (&(Vcb->DirtyMcbs), i, &DirtyVba, &DirtyLba, &DirtyLength); i++)
{
RfsdPrint((DBG_INFO, "DirtyVba = %I64xh\n", DirtyVba));
RfsdPrint((DBG_INFO, "DirtyLba = %I64xh\n", DirtyLba));
RfsdPrint((DBG_INFO, "DirtyLen = %I64xh\n\n", DirtyLength));
}
DbgBreak();
}
#endif
FsRtlUninitializeLargeMcb(&(Vcb->DirtyMcbs));
RfsdFreeMcbTree(Vcb->McbTree);
if (Vcb->GroupDesc) {
ExFreePool(Vcb->GroupDesc);
// CcUnpinData(Vcb->GroupDescBcb);
Vcb->GroupDesc = NULL;
}
if (Vcb->SuperBlock) {
ExFreePool(Vcb->SuperBlock);
Vcb->SuperBlock = NULL;
}
ExDeleteResourceLite(&Vcb->McbResource);
ExDeleteResourceLite(&Vcb->PagingIoResource);
ExDeleteResourceLite(&Vcb->MainResource);
IoDeleteDevice(Vcb->DeviceObject);
}
VOID
RfsdSyncUninitializeCacheMap (
IN PFILE_OBJECT FileObject
)
{
CACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent;
NTSTATUS WaitStatus;
LARGE_INTEGER RfsdLargeZero = {0,0};
KeInitializeEvent( &UninitializeCompleteEvent.Event,
SynchronizationEvent,
FALSE);
CcUninitializeCacheMap( FileObject,
&RfsdLargeZero,
&UninitializeCompleteEvent );
WaitStatus = KeWaitForSingleObject( &UninitializeCompleteEvent.Event,
Executive,
KernelMode,
FALSE,
NULL);
ASSERT (NT_SUCCESS(WaitStatus));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -