⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dskblk.c

📁 PDA上的CF CARD 文件系统的建立程式
💻 C
📖 第 1 页 / 共 3 页
字号:

		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 + -