📄 rfsd.c
字号:
} else {
CcUnpinData(BitmapBcb);
BitmapBcb = NULL;
BitmapCache = NULL;
RtlZeroMemory(&BlockBitmap, sizeof(RTL_BITMAP));
}
}
}
if (dwBlk < Length) {
RtlSetBits(&BlockBitmap, dwBlk, 1);
CcSetDirtyPinnedData(BitmapBcb, NULL );
RfsdRepinBcb(IrpContext, BitmapBcb);
CcUnpinData(BitmapBcb);
RfsdAddMcbEntry(Vcb, Offset.QuadPart, (LONGLONG)Vcb->BlockSize);
*dwRet = dwBlk + RFSD_FIRST_DATA_BLOCK + Group * BLOCKS_PER_GROUP;
//Updating Group Desc / Superblock
Vcb->GroupDesc[Group].bg_free_blocks_count--;
RfsdSaveGroup(IrpContext, Vcb, Group);
Vcb->SuperBlock->s_free_blocks_count--;
RfsdSaveSuper(IrpContext, Vcb);
{
ULONG i=0;
for (i=0; i < Vcb->NumOfGroups; i++)
{
if ((Vcb->GroupDesc[i].bg_block_bitmap == *dwRet) ||
(Vcb->GroupDesc[i].bg_inode_bitmap == *dwRet) ||
(Vcb->GroupDesc[i].bg_inode_table == *dwRet) ) {
DbgBreak();
GroupHint = Group;
goto ScanBitmap;
}
}
}
return STATUS_SUCCESS;
}
return STATUS_DISK_FULL;
#endif
}
NTSTATUS
RfsdFreeBlock(
PRFSD_IRP_CONTEXT IrpContext,
PRFSD_VCB Vcb,
ULONG Block )
{
DbgBreak();
#if DISABLED
RTL_BITMAP BlockBitmap;
LARGE_INTEGER Offset;
ULONG Length;
PBCB BitmapBcb;
PVOID BitmapCache;
ULONG Group, dwBlk;
BOOLEAN bModified = FALSE;
if ( Block < RFSD_FIRST_DATA_BLOCK ||
(Block / BLOCKS_PER_GROUP) >= Vcb->NumOfGroups) {
DbgBreak();
return STATUS_INVALID_PARAMETER;
}
RfsdPrint((DBG_INFO, "RfsdFreeBlock: Block %xh to be freed.\n", Block));
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 (!CcPinRead( Vcb->StreamObj,
&Offset,
Vcb->BlockSize,
PIN_WAIT,
&BitmapBcb,
&BitmapCache ) ) {
RfsdPrint((DBG_ERROR, "RfsdDeleteBlock: PinReading error ...\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlInitializeBitMap( &BlockBitmap,
BitmapCache,
Length );
if (RtlCheckBit(&BlockBitmap, dwBlk) == 0) {
} else {
RtlClearBits(&BlockBitmap, dwBlk, 1);
bModified = TRUE;
}
if (!bModified) {
CcUnpinData(BitmapBcb);
BitmapBcb = NULL;
BitmapCache = NULL;
RtlZeroMemory(&BlockBitmap, sizeof(RTL_BITMAP));
}
}
if (bModified) {
CcSetDirtyPinnedData(BitmapBcb, NULL );
RfsdRepinBcb(IrpContext, BitmapBcb);
CcUnpinData(BitmapBcb);
RfsdAddMcbEntry(Vcb, Offset.QuadPart, (LONGLONG)Vcb->BlockSize);
//Updating Group Desc / Superblock
Vcb->GroupDesc[Group].bg_free_blocks_count++;
RfsdSaveGroup(IrpContext, Vcb, Group);
Vcb->SuperBlock->s_free_blocks_count++;
RfsdSaveSuper(IrpContext, Vcb);
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
#endif
}
NTSTATUS
RfsdExpandBlock(
PRFSD_IRP_CONTEXT IrpContext,
PRFSD_VCB Vcb,
PRFSD_FCB Fcb,
ULONG dwContent,
ULONG Index,
ULONG layer,
BOOLEAN bNew,
ULONG *dwRet )
{
DbgBreak();
#if DISABLED
ULONG *pData = NULL;
ULONG i = 0, j = 0, temp = 1;
ULONG dwNewBlk = 0, dwBlk = 0;
BOOLEAN bDirty = FALSE;
NTSTATUS Status = STATUS_SUCCESS;
PRFSD_INODE Inode = Fcb->Inode;
PRFSD_SUPER_BLOCK RfsdSb = Vcb->SuperBlock;
pData = (ULONG *) ExAllocatePool(PagedPool, Vcb->BlockSize);
if (!pData) {
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(pData, Vcb->BlockSize);
if (bNew) {
if (layer == 0) {
if (IsDirectory(Fcb)) {
PRFSD_DIR_ENTRY2 pEntry;
pEntry = (PRFSD_DIR_ENTRY2) pData;
pEntry->rec_len = (USHORT)(Vcb->BlockSize);
if (!RfsdSaveBlock(IrpContext, Vcb, dwContent, (PVOID)pData)) {
Status = STATUS_UNSUCCESSFUL;
goto errorout;
}
} else {
LARGE_INTEGER Offset;
Offset.QuadPart = (LONGLONG) dwContent;
Offset.QuadPart = Offset.QuadPart * Vcb->BlockSize;
RfsdRemoveMcbEntry(Vcb, Offset.QuadPart, (LONGLONG)Vcb->BlockSize);
}
} else {
if (!RfsdSaveBlock(IrpContext, Vcb, dwContent, (PVOID)pData)) {
Status = STATUS_UNSUCCESSFUL;
goto errorout;
}
}
}
if (layer == 0) {
dwNewBlk = dwContent;
} else if (layer <= 3) {
if (!bNew) {
if (!RfsdLoadBlock(Vcb, dwContent, (void *)pData)) {
Status = STATUS_UNSUCCESSFUL;
goto errorout;
}
}
temp = 1 << ((BLOCK_BITS - 2) * (layer - 1));
i = Index / temp;
j = Index % temp;
dwBlk = pData[i];
if (dwBlk == 0) {
Status = RfsdNewBlock(
IrpContext,
Vcb, 0,
dwContent,
&dwBlk);
if (!NT_SUCCESS(Status)) {
RfsdPrint((DBG_ERROR, "RfsdExpandBlock: get new block error.\n"));
goto errorout;
}
Inode->i_blocks += (Vcb->BlockSize / SECTOR_SIZE);
pData[i] = dwBlk;
bDirty = TRUE;
}
Status = RfsdExpandBlock(
IrpContext,
Vcb, Fcb,
dwBlk, j,
layer - 1,
bDirty,
&dwNewBlk );
if (!NT_SUCCESS(Status))
{
RfsdPrint((DBG_ERROR, "RfsdExpandBlockk: ... error recuise...\n"));
goto errorout;
}
if (bDirty)
{
RfsdSaveBlock( IrpContext,
Vcb, dwContent,
(void *)pData );
}
}
errorout:
if (pData)
ExFreePool(pData);
if (NT_SUCCESS(Status) && dwRet)
*dwRet = dwNewBlk;
return Status;
#endif
}
NTSTATUS
RfsdExpandInode(
IN PRFSD_IRP_CONTEXT IrpContext,
IN PRFSD_VCB Vcb,
IN PRFSD_FCB Fcb,
OUT PULONG dwRet
)
{
DbgBreak();
#if DISABLED
ULONG dwSizes[RFSD_BLOCK_TYPES];
ULONG Index = 0;
ULONG dwTotal = 0;
ULONG dwBlk = 0, dwNewBlk = 0;
ULONG i;
NTSTATUS Status = STATUS_SUCCESS;
BOOLEAN bNewBlock = FALSE;
PRFSD_INODE Inode = Fcb->Inode;
Index = (ULONG)(Fcb->Header.AllocationSize.QuadPart >> BLOCK_BITS);
for (i = 0; i < RFSD_BLOCK_TYPES; i++) {
dwSizes[i] = Vcb->dwData[i];
dwTotal += dwSizes[i];
}
if (Index >= dwTotal) {
RfsdPrint((DBG_ERROR, "RfsdExpandInode: beyond the maxinum size of an inode.\n"));
return STATUS_UNSUCCESSFUL;
}
for (i = 0; i < RFSD_BLOCK_TYPES; i++) {
if (Index < dwSizes[i]) {
dwBlk = Inode->i_block[i==0 ? (Index):(i + RFSD_NDIR_BLOCKS - 1)];
if (dwBlk == 0) {
Status = RfsdNewBlock(
IrpContext,
Vcb,
Fcb->BlkHint ? 0 : ((Fcb->RfsdMcb->Inode - 1) / INODES_PER_GROUP),
Fcb->BlkHint,
&dwBlk );
if (!NT_SUCCESS(Status) ) {
RfsdPrint((DBG_ERROR, "RfsdExpandInode: get new block error.\n"));
break;
}
Inode->i_block[i==0 ? (Index):(i + RFSD_NDIR_BLOCKS - 1)] = dwBlk;
Inode->i_blocks += (Vcb->BlockSize / SECTOR_SIZE);
bNewBlock = TRUE;
}
Status = RfsdExpandBlock (
IrpContext,
Vcb, Fcb,
dwBlk, Index,
i, bNewBlock,
&dwNewBlk );
if (NT_SUCCESS(Status)) {
Fcb->Header.AllocationSize.QuadPart += Vcb->BlockSize;
}
break;
}
Index -= dwSizes[i];
}
RfsdSaveInode(IrpContext, Vcb, Fcb->RfsdMcb->Inode, Inode);
if (NT_SUCCESS(Status)) {
if (dwNewBlk) {
if (dwRet) {
Fcb->BlkHint = dwNewBlk+1;
*dwRet = dwNewBlk;
RfsdPrint((DBG_INFO, "RfsdExpandInode: %S (%xh) i=%2.2xh Index=%8.8xh New Block=%8.8xh\n",
Fcb->RfsdMcb->ShortName.Buffer, Fcb->RfsdMcb->Inode, i, Index, dwNewBlk));
}
} else {
DbgBreak();
Status = STATUS_UNSUCCESSFUL;
}
}
return Status;
#endif
}
NTSTATUS
RfsdNewInode(
PRFSD_IRP_CONTEXT IrpContext,
PRFSD_VCB Vcb,
ULONG GroupHint,
ULONG Type,
PULONG Inode )
{
DbgBreak();
#if DISABLED
RTL_BITMAP InodeBitmap;
PVOID BitmapCache;
PBCB BitmapBcb;
ULONG Group, i, j;
ULONG Average, Length;
LARGE_INTEGER Offset;
ULONG dwInode;
*Inode = dwInode = 0XFFFFFFFF;
repeat:
Group = i = 0;
if (Type == RFSD_FT_DIR) {
Average = Vcb->SuperBlock->s_free_inodes_count / Vcb->NumOfGroups;
for (j = 0; j < Vcb->NumOfGroups; j++) {
i = (j + GroupHint) % (Vcb->NumOfGroups);
if ((Vcb->GroupDesc[i].bg_used_dirs_count << 8) <
Vcb->GroupDesc[i].bg_free_inodes_count ) {
Group = i + 1;
break;
}
}
if (!Group) {
for (j = 0; j < Vcb->NumOfGroups; j++) {
if (Vcb->GroupDesc[j].bg_free_inodes_count >= Average) {
if (!Group || (Vcb->GroupDesc[j].bg_free_blocks_count >
Vcb->GroupDesc[Group].bg_free_blocks_count ))
Group = j + 1;
}
}
}
} else {
/*
* Try to place the inode in its parent directory (GroupHint)
*/
if (Vcb->GroupDesc[GroupHint].bg_free_inodes_count) {
Group = GroupHint + 1;
} else {
i = GroupHint;
/*
* Use a quadratic hash to find a group with a
* free inode
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -