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

📄 dskblk.c

📁 PDA上的CF CARD 文件系统的建立程式
💻 C
📖 第 1 页 / 共 3 页
字号:
/*************************************************************
File Name: DSKBLK.C (RAMDisk 4.0)			     *
**************************************************************
Programmer: MSC
Last Modified Date: 2000/08/16
Compiler : GNU Cross-compiler/SDS
Platform : X86 protection mode, MIPS, Dragonball
Usage :
	Disk block functions
*************************************************************/
#include <sys/syscall.h>

#include <stdio.h>

#include <ramdisk.h>
//#include "myansi.h"
#include <dskblk.h>
#include <piece.h>

// added by chilong 01/31/2002
extern unsigned long 	RD_DiskSize;


#ifdef RAMDISK_ID



struct diskBlock *RD_FirstFreeBlock = NULL;	// allocation starts from this free block


/* basic.c */
extern unsigned char *RAMMemory;	// the starting location of the RAMDisk's memory block
//extern unsigned long DiskSize;		// size of the RAMDisk in bytes
//extern int RDerrno;
extern void *RD_BootBegin;
//extern unsigned long RDLowerBoundary;
//extern unsigned long RDUpperBoundary;

/* piece.c */
extern void **RD_PLT;
extern unsigned long RDPieceSize;


//int freePrint = 0;
//extern char StrTemp[80];


void memoryZero(void *source, unsigned int size);


/*************************************************************
Function: initBlock
Description:
	initialize the RAMDisk memory pool
Input:
	size - the size of the memory pool
Output:
	NONE
**************************************************************/
/*
void initBlock(unsigned long size)
{
  // the starting address of the RAMDisk memory pool
  RD_FirstFreeBlock = (struct diskBlock *)RAMMemory;
  RD_FirstFreeBlock->size = size - B_HEADER - B_TAIL;
  RD_FirstFreeBlock->prevBlock = NULL;
  RD_FirstFreeBlock->nextBlock = NULL;
  RD_FirstFreeBlock->dataSize = 0;
  RD_FirstFreeBlock->actualSize = 0;
  RD_FirstFreeBlock->status = BLOCK_FREE;
  RD_FirstFreeBlock->userCount = 0;
  *((long *)((unsigned long)RD_FirstFreeBlock + size - B_TAIL)) = RD_FirstFreeBlock->size;
}
*/



#ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK
int RD_getBlock_2(struct diskBlock **allocBlock, unsigned long wantSize)
{
  struct diskBlock *blkPtr1;		// search block for needed
  struct diskBlock *blkPtr2;		// pointer followed with blkPtr1

  blkPtr1 = RD_FirstFreeBlock;
  blkPtr2 = NULL;

  while (blkPtr1 != NULL)
  {
	if (RD_checkBlockLocation(blkPtr1) == -1)
	{
		// block pointer out of bound
		RDerrno = ERROR_FILE_SYSTEM;
		return -1;
	}

	if (blkPtr1->size > (wantSize + B_HEADER + B_TAIL))
	{
		// the allocated block is cut from the beginning of the free block
		// blkPtr1 points to the allocated block
		// blkPtr2 points to the remaining free block
		// set blkPtr2
		blkPtr2 = (struct diskBlock *)((unsigned long)blkPtr1 + wantSize + B_HEADER + B_TAIL);
		// set the links between the new free block and the previous free block
		if (blkPtr1->prevBlock != NULL)
		{
			if (((struct diskBlock *)(blkPtr1->prevBlock))->nextBlock == (void *)blkPtr1)
			{
				// the link is valid
				((struct diskBlock *)(blkPtr1->prevBlock))->nextBlock = (void *)blkPtr2;
			}
			else
			{
				// the link is invalid
				RDerrno = ERROR_FILE_SYSTEM;
				return -1;
			}
		}
		blkPtr2->prevBlock = blkPtr1->prevBlock;
		// set the links between the new free block and the next free block
		if (blkPtr1->nextBlock != NULL)
		{
			if (((struct diskBlock *)(blkPtr1->nextBlock))->prevBlock == (void *)blkPtr1)
			{
				// the link is valid
				((struct diskBlock *)(blkPtr1->nextBlock))->prevBlock = (void *)blkPtr2;
			}
			else
			{
				// the link is invalid
				// undo the previous changed
				((struct diskBlock *)(blkPtr1->prevBlock))->nextBlock = (void *)blkPtr1;
				RDerrno = ERROR_FILE_SYSTEM;
				return -1;
			}
		}
		blkPtr2->nextBlock = blkPtr1->nextBlock;
		blkPtr2->size = blkPtr1->size - wantSize - B_HEADER - B_TAIL;
		*((long *)((unsigned long)blkPtr2 + B_HEADER + blkPtr2->size)) = blkPtr2->size;
		blkPtr2->dataSize = 0;
		blkPtr2->actualSize = 0;
		blkPtr2->status = BLOCK_FREE;
		blkPtr2->userCount = 0;

		// set blkPtr1
		blkPtr1->prevBlock = NULL;
		blkPtr1->nextBlock = NULL;
		blkPtr1->size = wantSize;
		*((long *)((unsigned long)blkPtr1 + B_HEADER + blkPtr1->size)) = wantSize;
		blkPtr1->dataSize = 0;
		blkPtr1->actualSize = 0;
		blkPtr1->status = BLOCK_UNCOMPRESSED;
		blkPtr1->userCount = 0;

		break;
	}
	// chilong: blkPtr1->size is the value which has substracted B_HEADER & B_TAIL
	//	see addNewPieceToFBL() in dskblk.c
	else if (blkPtr1->size >= wantSize)
	{
		// the current block has size matches the required size
		//   so the whole block is allocated uncut
		if (blkPtr2 != NULL)
		{
			if (blkPtr2->nextBlock == blkPtr1)
			{
				// link is valid
				blkPtr2->nextBlock = blkPtr1->nextBlock;
			}
			else
			{
				// link is invalid
				RDerrno = ERROR_FILE_SYSTEM;
				return -1;
			}
		}

		blkPtr2 = blkPtr1->nextBlock;
		if (blkPtr2 != NULL)
		{
			if (blkPtr2->prevBlock == blkPtr1)
			{
				// link is valid
				blkPtr2->prevBlock = blkPtr1->prevBlock;
			}
			else
			{
				// link is invalid
				// undo the previous change
				blkPtr2 = blkPtr1->prevBlock;
				blkPtr2->nextBlock = blkPtr1;
				RDerrno = ERROR_FILE_SYSTEM;
				return -1;
			}
		}

		blkPtr1->prevBlock = NULL;
		blkPtr1->nextBlock = NULL;
		blkPtr1->dataSize = 0;
		blkPtr1->actualSize = 0;
		blkPtr1->status = BLOCK_UNCOMPRESSED;
		blkPtr1->userCount = 0;

		break;
	}

	blkPtr2 = blkPtr1;
	blkPtr1 = (struct diskBlock *)blkPtr1->nextBlock;
  }

  if (blkPtr1 != NULL && blkPtr1 == RD_FirstFreeBlock)
  {
	RD_FirstFreeBlock = blkPtr2;
	((struct signature *)RD_BootBegin)->freeBegin = (void *)RD_FirstFreeBlock;
  }

  *allocBlock = blkPtr1;

  return 0;
}
#endif	// RAMDISK_USE_VARIABLE_SIZE_BLOCK



/*************************************************************
Function: RD_getBlock
Description:
	get a disk block of specified size from the RAMDisk memory pool
Input:
	wantSize - the required size
Output:
	NON NULL - the pointer to the allocated disk block
	NULL	 - allocation failed
Notes:
	The requierd block is always cut from the end of a free block.
**************************************************************/
void *RD_getBlock(unsigned long wantSize)
{
  void *ret;

  enterKernelCriticalSection();

  ret = RD_getBlock_r(wantSize);

  exitKernelCriticalSection();

  return ret;
}


/*************************************************************
Function: RD_getBlock_r
Description:
	get a disk block of specified size from the RAMDisk memory pool
Input:
	wantSize - the required size
Output:
	NON NULL - the pointer to the allocated disk block
	NULL	 - allocation failed
Notes:
	The requierd block is always cut from the end of a free block.
**************************************************************/
void *RD_getBlock_r(unsigned long wantSize)
{
#ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK

  struct diskBlock *blkPtr1;		// search block for needed
//  struct diskBlock *blkPtr2;		// pointer followed with blkPtr1

  if (wantSize == 0)
	return NULL;

  // integer-aligned
  if ((wantSize & 3) != 0)
	wantSize += (4 - (wantSize & 3));
/*
  blkPtr1 = RD_FirstFreeBlock;
  blkPtr2 = RD_FirstFreeBlock;

  while (blkPtr1 != NULL)
  {
	if (((unsigned long)blkPtr1 < RDLowerBoundary) || ((unsigned long)blkPtr1 >= RDUpperBoundary))
	{
		// block pointer out of bound
		RDerrno = ERROR_FILE_SYSTEM;
		return NULL;
	}

	if (blkPtr1->size > (wantSize + B_HEADER + B_TAIL))
	{
		// the allocated block is cut from the beginning of the free block
		// blkPtr1 points to the allocated block
		// blkPtr2 points to the remaining free block
		// set blkPtr2
		blkPtr2 = (struct diskBlock *)((unsigned long)blkPtr1 + wantSize + B_HEADER + B_TAIL);
		// set the links between the new free block and the previous free block
		if (blkPtr1->prevBlock != NULL)
		{
			if (((struct diskBlock *)(blkPtr1->prevBlock))->nextBlock == (void *)blkPtr1)
			{
				// the link is valid
				((struct diskBlock *)(blkPtr1->prevBlock))->nextBlock = (void *)blkPtr2;
			}
			else
			{
				// the link is invalid
				RDerrno = ERROR_FILE_SYSTEM
				return NULL;
			}
		}
		blkPtr2->prevBlock = blkPtr1->prevBlock;
		// set the links between the new free block and the next free block
		if (blkPtr1->nextBlock != NULL)
		{
			if (((struct diskBlock *)(blkPtr1->nextBlock))->prevBlock == (void *)blkPtr1)
			{
				// the link is valid
				((struct diskBlock *)(blkPtr1->nextBlock))->prevBlock = (void *)blkPtr2;
			}
			else
			{
				// the link is invalid
				// undo the previous changed
				((struct diskBlock *)(blkPtr1->prevBlock))->nextBlock = (void *)blkPtr1;
				RDerrno = ERROR_FILE_SYSTEM
				return NULL;
			}
		}
		blkPtr2->nextBlock = blkPtr1->nextBlock;
		blkPtr2->size = blkPtr1->size - wantSize - B_HEADER - B_TAIL;
		*((long *)((unsigned long)blkPtr2 + B_HEADER + blkPtr2->size)) = blkPtr2->size;
		blkPtr2->dataSize = 0;
		blkPtr2->actualSize = 0;
		blkPtr2->status = BLOCK_FREE;
		blkPtr2->userCount = 0;

		// set blkPtr1
		blkPtr1->prevBlock = NULL;
		blkPtr1->nextBlock = NULL;
		blkPtr1->size = wantSize;
		*((long *)((unsigned long)blkPtr1 + B_HEADER + blkPtr1->size)) = wantSize;
		blkPtr1->dataSize = 0;
		blkPtr1->actualSize = 0;
		blkPtr2->status = BLOCK_UNCOMPRESSED;
		blkPtr2->userCount = 0;

		break;
	}
	else if (blkPtr1->size >= wantSize)
	{
		// the current block has size matches the required size
		//   so the whole block is allocated uncut
		if (blkPtr2 != NULL)
		{
			if (blkPtr2->nextBlock == blkPtr1)
			{
				// link is valid
				blkPtr2->nextBlock = blkPtr1->nextBlock;
			}
			else
			{
				// link is invalid
				RDerrno = ERROR_FILE_SYSTEM
				return NULL;
			}
		}

		blkPtr2 = blkPtr1->nextBlock;
		if (blkPtr2 != NULL)
		{
			if (blkPtr2->prevBlock == blkPtr1)
			{
				// link is valid
				blkPtr2->prevBlock = blkPtr1->prevBlock;
			}
			else
			{
				// link is invalid
				// undo the previous change
				blkPtr2 = blkPtr1->prevBlock;
				blkPtr2->nextBlock = blkPtr1;
				RDerrno = ERROR_FILE_SYSTEM
				return NULL;
			}
		}

		blkPtr1->prevBlock = NULL;
		blkPtr1->nextBlock = NULL;
		blkPtr1->dataSize = 0;
		blkPtr1->actualSize = 0;
		blkPtr1->status = BLOCK_UNCOMPRESSED;
		blkPtr1->userCount = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -