📄 dskblk.c
字号:
/*************************************************************
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 + -