📄 dskblk.c
字号:
return;
}
if (prevBlock == NULL)
{
// the new block is added to the head of the free block list
RD_FirstFreeBlock = targetBlock;
((struct signature *)RD_BootBegin)->freeBegin = (void *)RD_FirstFreeBlock;
targetBlock->nextBlock = nextBlock;
nextBlock->prevBlock = targetBlock;
return;
}
// the new block is added at the middle of the free block list
prevBlock->nextBlock = targetBlock;
targetBlock->prevBlock = prevBlock;
nextBlock->prevBlock = targetBlock;
targetBlock->nextBlock = nextBlock;
return;
#endif // RAMDISK_USE_VARIABLE_SIZE_BLOCK
}
/*************************************************************
Function: RD_freeBlockLink
Description:
free all blocks in a file block link
Input:
startBlock - the starting block in the link
Output:
NONE
**************************************************************/
void RD_freeBlockLink(struct diskBlock *startBlock)
{
struct diskBlock *curBlock;
struct diskBlock *nextBlock;
curBlock = startBlock;
while (curBlock != NULL)
{
if (RD_checkBlockLocation(curBlock) == -1)
return; // block address out of bound
nextBlock = curBlock->nextBlock;
RD_freeBlock(curBlock);
curBlock = nextBlock;
}
// added by chilong 01/31/2002
RD_freeUnusedMemory();
return;
}
/*************************************************************
Function: RD_truncateBlock
Description:
truncate a block
Input:
block - the target block
newSize - the new size of the block
Output:
the pointer to the new block
Note:
The truncate is done at the head of the block, i.e., the
specified size of the tail part of the block is the new
block and the unused head part is freed. So make sure that
the block data has already been copied from the head part
to the tail part before calling this function. This is
done to increase the chance of free block merging.
**************************************************************/
struct diskBlock *RD_truncateBlock(struct diskBlock *block, unsigned long newSize)
{
struct diskBlock *result;
enterKernelCriticalSection();
result = RD_truncateBlock_r(block, newSize);
exitKernelCriticalSection();
return result;
}
struct diskBlock *RD_truncateBlock_r(struct diskBlock *block, unsigned long newSize)
{
#ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK
unsigned long mySize;
struct diskBlock *toFreeBlock;
long *tail;
if (newSize == 0)
return block;
// integer-aligned
mySize = (((newSize - 1) >> 2) + 1) << 2;
// truncate only if the new size is smaller
if (block->size <= mySize + ((B_HEADER + B_TAIL) >> 1))
return block;
// prepare the unused part as a free block
toFreeBlock = (struct diskBlock *)((unsigned long)block + mySize + B_HEADER + B_TAIL);
toFreeBlock->prevBlock = NULL;
toFreeBlock->nextBlock = NULL;
toFreeBlock->size = block->size - mySize - B_HEADER - B_TAIL;
toFreeBlock->dataSize = 0;
toFreeBlock->actualSize = 0;
toFreeBlock->status = BLOCK_FREE;
toFreeBlock->userCount = 0;
tail = (long *)((unsigned long)toFreeBlock + B_HEADER + toFreeBlock->size);
*tail = toFreeBlock->size;
// rebuild the block header
block->size = mySize;
block->dataSize = newSize;
tail = (long *)((unsigned long)block + B_HEADER + block->size);
*tail = mySize;
/**** added by chilong 9/27/2001 ****/
RD_writeBlockChecksum(block);
/**** added by chilong 9/27/2001 ****/
// free the unused part
RD_freeBlock_r(toFreeBlock);
return block;
#else // RAMDISK_USE_VARIABLE_SIZE_BLOCK
// no truncate with fixed block size
return block;
#endif // RAMDISK_USE_VARIABLE_SIZE_BLOCK
}
/*************************************************************
Function: RD_checkBlockLocation
Description:
check if the starting address of a block is valid
Input:
targetBlock - the starting address of the target block
Output:
0 - the location is valid
-1 - the location is invalid
**************************************************************/
int RD_checkBlockLocation(struct diskBlock *targetBlock)
{
int i;
unsigned long blockSize;
/**** added by chilong 10/3/2001 ****/
PIECE_DS *pPieceDS;
/**** added by chilong 10/3/2001 ****/
if (targetBlock == NULL)
return -1;
/**** added by chilong 10/29/2001 ****/
// Because ARM CPU is 4-byte aligned,
// we got to check if the address of the targetBlock
// is valid
if ((long)targetBlock % 4 != 0)
return -1;
/**** added by chilong 10/29/2001 ****/
/* marked by chilong 10/3/2001
for (i = 0; i < RD_PLT_ENTRY_NUM; i++)
{
if (RD_PLT[i] == NULL)
continue;
if (((unsigned long)targetBlock >= (unsigned long)(RD_PLT[i])) && ((unsigned long)targetBlock < (unsigned long)(RD_PLT[i]) + RDPieceSize))
{
blockSize = *((unsigned long *)((unsigned long)targetBlock + B_HEADER + targetBlock->size));
if (targetBlock->size == blockSize)
{
return 0;
}
else
{
return -1;
}
}
}
marked by chilong 10/3/2001 */
/**** modified by chilong 10/3/2001 ****/
for (i = 0; i < RD_PLT_ENTRY_NUM; i++)
{
pPieceDS = (PIECE_DS*) ((PIECE_DS*)RD_PLT + i);
if (pPieceDS->startAddress == NULL)
continue;
if (((unsigned long)targetBlock >= (unsigned long)(pPieceDS->startAddress)) &&
((unsigned long)targetBlock < (unsigned long)(pPieceDS->startAddress) + pPieceDS->size))
{
// blockSize = *((unsigned long *)((unsigned long)targetBlock + B_HEADER + targetBlock->size));
/**** modified by chilong 12/4/2001 ****/
// Because ARM CPU is 4-byte aligned,
// we got to check the address of the targetBlock
if (targetBlock->size % 4 != 0)
return -1;
blockSize = *((unsigned long *)((unsigned long)targetBlock + B_HEADER + targetBlock->size));
/**** modified by chilong 12/4/2001 ****/
if (targetBlock->size == blockSize)
{
return 0;
}
else
{
return -1;
}
}
}
/**** modified by chilong 10/3/2001 ****/
return -1;
}
/*************************************************************
Fuction : RD_writeBlockChecksum
write a check sum for a block
Input:
block - the block which will be filled with a checksum
Output:
0: no error is found
-1: error
**************************************************************/
int RD_writeBlockChecksum(struct diskBlock* blk)
{
int i;
long checksum = 0;
unsigned char* pBlock;
if (blk == NULL)
return -1;
if (RD_checkBlockLocation(blk) == -1)
return -1;
pBlock = (unsigned char *)((unsigned long)blk);
for (i = 0; i < (B_HEADER + blk->actualSize) / 4; i++)
{
checksum += *((int*)pBlock);
pBlock += 4;
}
for (i = 0; i < (B_HEADER + blk->actualSize) % 4; i++)
{
checksum += *(pBlock+i);
}
// record the checksum at the end of the block
*((long *)((unsigned long)blk + B_HEADER + blk->size + B_TAIL/2)) = checksum;
return 0;
}
/*************************************************************
Fuction : RD_checkBlockChecksum
write a check sum for a block
Input:
block - the block which will be filled with a checksum
Output:
0: no error is found
-1: error
**************************************************************/
int RD_checkBlockChecksum(struct diskBlock* blk)
{
int i;
long checksum = 0;
unsigned char* pBlock;
if (blk == NULL)
return -1;
if (RD_checkBlockLocation(blk) == -1)
return -1;
pBlock = (unsigned char *)((unsigned long)blk);
for (i = 0; i < (B_HEADER + blk->actualSize) / 4; i++)
{
checksum += *((int*)pBlock);
pBlock += 4;
}
for (i = 0; i < (B_HEADER + blk->actualSize) % 4; i++)
{
checksum += *(pBlock+i);
}
if (*((long *)((unsigned long)blk + B_HEADER + blk->size + B_TAIL/2)) != checksum)
return -1;
else
return 0;
}
/**** added by chilong 01/31/2002 ****/
/*************************************************************
Function: RD_freeUnusedMemory
Description:
check if the file is being opened
Input:
pfile
Output:
1: open
0: not open
**************************************************************/
void RD_freeUnusedMemory(void)
{
int i;
int total = 0;
char bNeed2ReadNext;
PIECE_DS *pPieceDS;
struct diskBlock *curBlock;
// start freeing ununsed space
curBlock = RD_FirstFreeBlock;
while(curBlock != NULL)
{
// we use "option" to keep track of whether or not
// we need to move curBlock to the next later.
if (RD_checkBlockLocation(curBlock) == -1)
break;
bNeed2ReadNext = 1;
for (i = 0; i < RD_PLT_ENTRY_NUM; i++)
{
pPieceDS = (PIECE_DS*) ((PIECE_DS*)RD_PLT + i);
//if (pPieceDS->startAddress != NULL)
// modified by chilong 02/07/2002
if (pPieceDS->startAddress != NULL && (unsigned long)pPieceDS->startAddress % 4 == 0)
{
// !!NOTE:
// about (pPieceDS->size - B_HEADER - B_TAIL),
// please refer to getPiece() & addNewPieceToFBL() in piece.c
if (curBlock == pPieceDS->startAddress &&
curBlock->size == (pPieceDS->size - B_HEADER - B_TAIL) )
{
// we move curBlock to the next block first
// because curBlock will be freed and
// set to NULL after invoking freePiece()
curBlock = curBlock->nextBlock;
freePiece((void*)pPieceDS->startAddress);
bNeed2ReadNext = 0;
break;
}
}
}
if (bNeed2ReadNext)
curBlock = curBlock->nextBlock;
}
}
/**** added by chilong 01/31/2002 ****/
#endif // #ifdef RAMDISK_ID
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -