📄 dskblk.c
字号:
break;
}
blkPtr2 = blkPtr1;
blkPtr1 = (struct diskBlock *)blkPtr1->nextBlock;
}
*/
if (RD_getBlock_2(&blkPtr1, wantSize) == -1)
return NULL; // get block failed
if (blkPtr1 == NULL)
{
// no free block or free blocks are not big enough
// get a new piece
// blkPtr1 = (struct diskBlock *)getPiece();
/**** added by chilng 10/2/2001 ****/
blkPtr1 = (struct diskBlock *)getPiece(wantSize);
/**** added by chilng 10/2/2001 ****/
if (blkPtr1 == NULL)
{
// can't get new piece, it's either disk full or insufficient free memory
// error code already in RDerrno
return NULL;
}
// the new block of the new piece have already been added to the head of the free block list
// get a new block from there
if (RD_getBlock_2(&blkPtr1, wantSize) == -1)
return NULL; // get block failed
}
// clear the block (fill it with 0)
memoryZero((void *)((unsigned long)blkPtr1 + B_HEADER), (unsigned int)wantSize);
/**** added by chilong 9/25/2001 ****/
RD_writeBlockChecksum(blkPtr1);
/**** added by chilong 9/25/2001 ****/
return ((void *)blkPtr1);
#else // RAMDISK_USE_VARIABLE_SIZE_BLOCK
struct diskBlock *newBlock;
if (RD_FirstFreeBlock == NULL)
{
// no free block left, get a piece
// newBlock = (struct diskBlock *)getPiece();
/**** modified by chilong 10/2/2001 ****/
newBlock = (struct diskBlock *)getPiece(wantSize);
/**** modified by chilong 10/2/2001 ****/
if (newBlock == NULL)
{
// can't get new piece, it's either disk full or insufficient free memory
// error code already in RDerrno
return NULL;
}
// the new blocks of the new piece have already been added to free block list
}
if (RD_checkBlockLocation(RD_FirstFreeBlock) == -1)
{
// the 1st free block is out of bound
RDerrno = ERROR_FILE_SYSTEM;
return NULL;
}
// take a free block from the head of the free block list
newBlock = RD_FirstFreeBlock;
RD_FirstFreeBlock = RD_FirstFreeBlock->nextBlock;
((struct signature *)RD_BootBegin)->freeBegin = (void *)RD_FirstFreeBlock;
RD_FirstFreeBlock->prevBlock = NULL;
// set new block infomation
newBlock->prevBlock = NULL;
newBlock->nextBlock = NULL;
newBlock->dataSize = 0;
newBlock->actualSize = 0;
newBlock->status = BLOCK_UNCOMPRESSED;
newBlock->userCount = 0;
return newBlock;
#endif // RAMDISK_USE_VARIABLE_SIZE_BLOCK
}
/*************************************************************
Function: RD_freeBlock
Description:
release a disk block back to the RAMDisk memory pool
Input:
block - the block that is going to be released
Output:
**************************************************************/
void RD_freeBlock(void *block)
{
enterKernelCriticalSection();
RD_freeBlock_r(block);
exitKernelCriticalSection();
}
/*************************************************************
Function: RD_freeBlock_r
Description:
release a disk block back to the RAMDisk memory pool
Input:
block - the block that is going to be released
Output:
**************************************************************/
void RD_freeBlock_r(void *block)
{
#ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK
struct diskBlock *blkPtr1; // search block for needed
struct diskBlock *blkPtr2; // pointer followed with blkPtr1
struct diskBlock *memToFree;
int index;
/**** added by chilong 10/3/2001 ****/
PIECE_DS *pPieceDS;
/**** added by chilong 10/3/2001 ****/
if (block == NULL)
return;
if (RD_checkBlockLocation(block) == -1)
{
RDerrno = ERROR_FILE_SYSTEM;
return;
}
/* marked by chilong 10/3/2001
// found the piece in which the target block is located
for (index = 0; index < RD_PLT_ENTRY_NUM; index++)
{
if ((unsigned long)block >= (unsigned long)(RD_PLT[index]) && (unsigned long)block < (unsigned long)(RD_PLT[index]) + RDPieceSize)
{
// the block is within RD_PLT[index]
break;
}
}
marked by chilong 10/3/2001 */
/**** modified by chilong 10/3/2001 ****/
// found the piece in which the target block is located
for (index = 0; index < RD_PLT_ENTRY_NUM; index++)
{
pPieceDS = (PIECE_DS*) ((PIECE_DS*)RD_PLT + index);
if (pPieceDS->startAddress != NULL)
{
if ((unsigned long)block >= (unsigned long)(pPieceDS->startAddress) &&
(unsigned long)block < (unsigned long)(pPieceDS->startAddress) + pPieceDS->size)
{
// the block is within RD_PLT[index]
break;
}
}
}
/**** modified by chilong 10/3/2001 ****/
if (index == RD_PLT_ENTRY_NUM)
{
// the block is not in anyone of the existing pieces
RDerrno = ERROR_FILE_SYSTEM;
return;
}
memToFree = (struct diskBlock *)block;
// clear the header of the block
memToFree->prevBlock = NULL;
memToFree->nextBlock = NULL;
memToFree->dataSize = 0;
memToFree->actualSize = 0;
memToFree->status = BLOCK_FREE;
memToFree->userCount = 0;
//----------------------------------------------------
// free block to RAMDisk memory pool
if (RD_FirstFreeBlock == NULL)
{
RD_FirstFreeBlock = memToFree;
/**** added by chilong 9/25/2001 ****/
RD_writeBlockChecksum(memToFree);
/**** added by chilong 9/25/2001 ****/
return;
}
// find a suitable position for the addition of the new free block to the free block list
blkPtr1 = RD_FirstFreeBlock;
blkPtr2 = NULL;
while (blkPtr1 < memToFree)
{
blkPtr2 = blkPtr1;
blkPtr1 = blkPtr1->nextBlock;
if (blkPtr1 == NULL)
break;
if (RD_checkBlockLocation(blkPtr1) == -1)
{
// block address out of bound
RDerrno = ERROR_FILE_SYSTEM;
return;
}
}
/*
if (freePrint == 1)
{
sprintf(StrTemp, "[RD_freeBlock_r]");
SprintStringLn(StrTemp);
sprintf(StrTemp, "currBlock: %x", memToFree);
SprintStringLn(StrTemp);
if (blkPtr2 == NULL)
{
sprintf(StrTemp, "blkPtr2: %x", blkPtr2);
SprintStringLn(StrTemp);
}
else
{
sprintf(StrTemp, "blkPtr2: %x(%x)(%x)", blkPtr2, blkPtr2->prevBlock, blkPtr2->nextBlock);
SprintStringLn(StrTemp);
}
if (blkPtr1 == NULL)
{
sprintf(StrTemp, "blkPtr1: %x", blkPtr1);
SprintStringLn(StrTemp);
}
else
{
sprintf(StrTemp, "blkPtr1: %x(%x)(%x)", blkPtr1, blkPtr1->prevBlock, blkPtr1->nextBlock);
SprintStringLn(StrTemp);
}
}
*/
// now blkPtr2 < memToFree and blkPtr1 > memToFree
// process blkPtr2 and memToFree
if (blkPtr2 == NULL)
{
// the new free block is added to the head of the free block list
RD_FirstFreeBlock = memToFree;
((struct signature *)RD_BootBegin)->freeBegin = (void *)RD_FirstFreeBlock;
memToFree->prevBlock = NULL;
}
else
{
// check if blkPtr2 can be merged with the new free block
// if ((unsigned long)memToFree > (unsigned long)(RD_PLT[index]))
/**** modified by chilong 10/4/2001 ****/
if ((unsigned long)memToFree > (unsigned long) pPieceDS->startAddress)
/**** modified by chilong 10/4/2001 ****/
{
// the new block is not at the head of its storing piece
// merging is possible
if ((unsigned long)memToFree == ((unsigned long)blkPtr2 + blkPtr2->size + B_HEADER + B_TAIL))
{
// the new block and blkPtr2 are neighboring blocks, can be merged
blkPtr2->size += (memToFree->size + B_HEADER + B_TAIL);
*((long *)((unsigned long)blkPtr2 + B_HEADER + blkPtr2->size)) = blkPtr2->size;
memToFree = blkPtr2;
}
else
{
// not neighboring blocks, cannot be merged
blkPtr2->nextBlock = memToFree;
memToFree->prevBlock = blkPtr2;
}
}
else
{
// the new block is at the head of its storing piece
// cannot merge with blkPtr2
blkPtr2->nextBlock = memToFree;
memToFree->prevBlock = blkPtr2;
}
}
// process memToFree and blkPtr1
if (blkPtr1 == NULL)
{
// memToFree is the last block in the list
memToFree->nextBlock = NULL;
}
else
{
// check if blkPtr1 can be merged with the new free block
// if (((unsigned long)memToFree + B_HEADER + memToFree->size + B_TAIL) < ((unsigned long)(RD_PLT[index]) + RDPieceSize))
/**** modified by chilong 10/3/2001 ****/
if (((unsigned long)memToFree + B_HEADER + memToFree->size + B_TAIL) <
((unsigned long)(pPieceDS->startAddress) + pPieceDS->size))
/**** modified by chilong 10/3/2001 ****/
{
// the new block is not the last block in the piece
// so merging with the is possible
if (((unsigned long)memToFree + B_HEADER + memToFree->size + B_TAIL) == (unsigned long)blkPtr1)
{
// the two blocks are neighboring blocks, can be merged
memToFree->size += (blkPtr1->size + B_HEADER + B_TAIL);
*((long *)((unsigned long)memToFree + B_HEADER + memToFree->size)) = memToFree->size;
memToFree->nextBlock = blkPtr1->nextBlock;
blkPtr1 = (struct diskBlock *)blkPtr1->nextBlock;
if (blkPtr1 != NULL)
blkPtr1->prevBlock = memToFree;
}
else
{
// not neighboring blocks, cannot be merged
memToFree->nextBlock = blkPtr1;
blkPtr1->prevBlock = memToFree;
}
}
else
{
// the new block is at the end of its storing piece
// merging is impossible
memToFree->nextBlock = blkPtr1;
blkPtr1->prevBlock = memToFree;
}
}
/**** added by chilong 9/25/2001 ****/
RD_writeBlockChecksum(memToFree);
/**** added by chilong 9/25/2001 ****/
return;
#else // RAMDISK_USE_VARIABLE_SIZE_BLOCK
struct diskBlock *targetBlock;
struct diskBlock *prevBlock;
struct diskBlock *nextBlock;
targetBlock = (struct diskBlock *)block;
// clear the header of the block
targetBlock->prevBlock = NULL;
targetBlock->nextBlock = NULL;
targetBlock->dataSize = 0;
targetBlock->actualSize = 0;
targetBlock->status = BLOCK_FREE;
targetBlock->userCount = 0;
if (RD_FirstFreeBlock == NULL)
{
// the free block list is empty
RD_FirstFreeBlock = targetBlock;
((struct signature *)RD_BootBegin)->freeBegin = (void *)RD_FirstFreeBlock;
return;
}
// find the suitable position in the free block list for the freed block
// remember that the list is sort ascendingly according to the addresses of the free blocks
nextBlock = RD_FirstFreeBlock;
prevBlock = NULL;
while (nextBlock != NULL)
{
if (nextBlock > targetBlock)
break;
prevBlock = nextBlock;
nextBlock = nextBlock->nextBlock;
}
if (nextBlock == NULL)
{
// the new block is added to the tail of the free block list
prevBlock->nextBlock = targetBlock;
targetBlock->prevBlock = prevBlock;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -