📄 fio.c
字号:
if (curBlock != NULL)
{
if (RD_checkBlockLocation(curBlock) == -1)
{
RDerrno = ERROR_FILE_SYSTEM;
return -1;
}
// there is a current block, compress the block if (1) compression for
// this file is enabled, (2) the block is uncompressed, and (3) the block
// is the current block of only one file handle
if ((((pfile->dirEntry)->attribute & DA_COMPRESS) == DA_COMPRESS) && \
(curBlock->status == BLOCK_UNCOMPRESSED) && \
(curBlock->userCount == 1))
{
// compression enabled and the block is uncompressed, compress the block
// get a buffer
buf = (int *)ap_malloc(RD_BLOCK_SIZE);
if (buf == NULL)
{
RDerrno = ERROR_ALLOC_MEM;
return -1;
}
// copy the content of the original block to the buffer
// this copying is used instead of directly compress the
// data in the target block so that RAMDisk can recover
// the disk content in case the compression failed.
src = (int*)((unsigned long)curBlock + B_HEADER);
loop = curBlock->size / sizeof(int);
for (i = 0; i < loop; i++)
buf[i] = src[i];
newSize = rd_compress_zlib((unsigned char *)src, curBlock->actualSize);
if (newSize == -1 || newSize >= curBlock->actualSize)
{
// compression failed, recover the original content
loop = curBlock->size / sizeof(int);
for (i = 0; i < loop; i++)
src[i] = buf[i];
RDerrno = ERROR_BLOCK_COMPRESS;
returnValue = -1;
}
else
{
// compression done
// // copy the compressed data from the head to the tail of the block
// loop = ((newSize - 1) / sizeof(int)) + 1;
// src = (int*)((unsigned long)curBlock + B_HEADER + (loop * sizeof(int)) - sizeof(int));
// des = (int*)((unsigned long)curBlock + B_HEADER + curBlock->size - sizeof(int));
// for (i = 0; i < loop; i++)
// *des-- = *src--;
// truncate the block so that only the compressed data region is left
newBlock = RD_truncateBlock(curBlock, newSize);
/*
if (newBlock != curBlock)
{
// update the link to the next block
if (newBlock->nextBlock != NULL)
((struct diskBlock *)(newBlock->nextBlock))->prevBlock = newBlock;
// update the link to the previous block
// If there is no previous block, then the current block
// is the starting block and the directory entry must be
// updated.
if (newBlock->prevBlock == NULL)
(pfile->dirEntry)->startBlock = newBlock;
else
((struct diskBlock *)(newBlock->prevBlock))->nextBlock = newBlock;
newBlock->status = BLOCK_COMPRESSED;
pfile->currentBlock = newBlock;
}
*/
newBlock->status = BLOCK_COMPRESSED;
pfile->currentBlock = newBlock;
}
ap_free(buf);
}
}
// !!Note: in RD_truncate_r(), we've done RD_writeBlockChecksum() once.
// But because newBlock->status is changned here, we have to
// write it again. This might lead to a bit slow performance. Watch Out!!
RD_writeBlockChecksum(newBlock);
return returnValue;
}
#endif // #ifdef RAMDISK_COMPRESS_USE_ZLIB
#ifdef RAMDISK_COMPRESS_USE_ZLIB
/*************************************************************
Function: uncompressCurrentBlock
Description:
Uncompress the current block of a file handle
Input:
file handle
Output:
0: Success
-1: Failure
**************************************************************/
int uncompressCurrentBlock(struct RD_FILE *pfile)
{
int *des;
long expandedSize;
struct diskBlock *curBlock;
struct diskBlock *theBlock;
curBlock = pfile->currentBlock;
// check if the current block should be uncompressed
if (curBlock != NULL)
{
if (RD_checkBlockLocation(curBlock) == -1)
{
RDerrno = ERROR_FILE_SYSTEM;
return -1;
}
// there is a current block, uncompress the block if the block is compressed
if (curBlock->status == BLOCK_COMPRESSED)
{
// the block is compressed, uncompress the block
if (curBlock->userCount > 1)
{
// there are more than 1 handles using this block
// it is impossible that this block is still uncompressed
RDerrno = ERROR_FILE_STRUCTURE;
return -1;
}
// get a block for uncompression
theBlock = RD_getBlock(RD_BLOCK_SIZE);
if (theBlock == NULL)
{
RDerrno = ERROR_ALLOC_BLOCK;
return -1;
}
// copy the content of the original block to the buffer
// this copying is used instead of directly compress the
// data in the target block so that RAMDisk can recover
// the disk content in case the compression failed.
des = (int*)((unsigned long)theBlock + B_HEADER);
expandedSize = rd_uncompress_zlib(curBlock, des);
if (expandedSize == -1 || expandedSize != curBlock->actualSize)
{
// uncompression failed
RD_freeBlock(theBlock);
RDerrno = ERROR_BLOCK_UNCOMPRESS;
return -1;
}
else
{
// uncompression done
// replace the compressed block by the uncompressed block in
// the file's block link
theBlock->dataSize = expandedSize;
theBlock->actualSize = expandedSize;
theBlock->status = BLOCK_UNCOMPRESSED;
theBlock->userCount = curBlock->userCount;
theBlock->prevBlock = curBlock->prevBlock;
theBlock->nextBlock = curBlock->nextBlock;
// update the link to the next block
if (theBlock->nextBlock != NULL)
((struct diskBlock *)(theBlock->nextBlock))->prevBlock = theBlock;
// update the link to the previous block
// If there is no previous block, then the current block
// is the starting block and the directory entry must be
// updated.
if (theBlock->prevBlock == NULL)
(pfile->dirEntry)->startBlock = theBlock;
else
((struct diskBlock *)(theBlock->prevBlock))->nextBlock = theBlock;
pfile->currentBlock = theBlock;
RD_freeBlock(curBlock);
}
}
}
RD_writeBlockChecksum(theBlock);
return 0;
}
#endif // #ifdef RAMDISK_COMPRESS_USE_ZLIB
/*************************************************************
Function : RD_read
Description:
read data from file to user buffer
Inputs :
fhandle - file handle
buffer - user specified buffer
size - size of data to be read
Outputs :
the size of data read from disk
**************************************************************/
long RD_read(int fhandle, void *buffer, unsigned long size)
{
long result;
#ifdef RAMDISK_STAT_LOG
unsigned long startTime, endTime;
struct signature *boot = (struct signature *)RD_BootBegin;
#endif
if (InitRD == FALSE)
{
RDerrno = ERROR_FILE_SYSTEM_NOT_INIT;
return 0;
}
if ((fhandle < 0) || (fhandle >= MAX_OPEN_FILE) || (RD_HandleTable[fhandle] == NULL))
{
RDerrno = ERROR_INVALID_HANDLE;
return 0;
}
if (RD_HandleTable[fhandle]->deviceID != RAMDISK_ID)
{
RDerrno = ERROR_INVALID_DEVICE;
return 0;
}
RDerrno = 0;
if (size == 0)
return 0;
if (sc_waitSemaphore(RD_SemaphoreID) == -1)
{
RDerrno = ERROR_WAIT_SEMAPHORE;
return 0;
}
#ifdef RAMDISK_STAT_LOG
startTime = sc_getTimeStamp();
#endif
result = RD_read_r(RD_HandleTable[fhandle], buffer, size);
RD_updateFileHandleTable(RD_HandleTable[fhandle]);
#ifdef RAMDISK_STAT_LOG
endTime = sc_getTimeStamp();
if (endTime > startTime)
{
boot->readTime += (endTime - startTime);
}
boot->readCount += result;
#endif
if (sc_signalSemaphore(RD_SemaphoreID) == -1)
{
RDerrno = ERROR_SIGNAL_SEMAPHORE;
return 0;
}
return result;
}
/*************************************************************
Function : RD_write
Description:
write data from user buffer to file
Inputs :
fhandle - file handle
buffer - user specified buffer
size - size of data to be written
Outputs :
the size of data written to disk
**************************************************************/
long RD_write(int fhandle, void *buffer, unsigned long size)
{
long result;
#ifdef RAMDISK_STAT_LOG
unsigned long startTime, endTime;
struct signature *boot = (struct signature *)RD_BootBegin;
#endif
if (InitRD == FALSE)
{
RDerrno = ERROR_FILE_SYSTEM_NOT_INIT;
return 0;
}
if ((fhandle < 0) || (fhandle >= MAX_OPEN_FILE) || (RD_HandleTable[fhandle] == NULL))
{
RDerrno = ERROR_INVALID_HANDLE;
return 0;
}
if (RD_HandleTable[fhandle]->deviceID != RAMDISK_ID)
{
RDerrno = ERROR_INVALID_DEVICE;
return 0;
}
if ((RD_HandleTable[fhandle]->fileFlag & O_RDWR) == 0)
{
RDerrno = ERROR_FILE_FLAG;
return 0;
}
RDerrno = 0;
if (size == 0)
return 0;
if (sc_waitSemaphore(RD_SemaphoreID) == -1)
{
RDerrno = ERROR_WAIT_SEMAPHORE;
return 0;
}
#ifdef RAMDISK_STAT_LOG
startTime = sc_getTimeStamp();
#endif
result = RD_write_r(RD_HandleTable[fhandle], buffer, size);
RD_updateFileHandleTable(RD_HandleTable[fhandle]);
#ifdef RAMDISK_STAT_LOG
endTime = sc_getTimeStamp();
if (endTime > startTime)
{
boot->writeTime += (endTime - startTime);
}
boot->writeCount += result;
#endif
if (sc_signalSemaphore(RD_SemaphoreID) == -1)
{
RDerrno = ERROR_SIGNAL_SEMAPHORE;
return 0;
}
return result;
}
/*************************************************************
Function: RD_flush
Description:
clear the buffer in file handle
Input:
fhandle - the target file handle
Output:
0 SUCCESS
-1 FAILURE
Note:
**************************************************************/
int RD_flush(int fhandle)
{
RDerrno = 0;
return 0;
}
/*************************************************************
Function: RD_flushAll
Description:
clear the buffers in all file handles
Input:
NONE
Output:
0 SUCCESS
-1 FAILURE
Note:
**************************************************************/
int RD_flushAll(void)
{
RDerrno = 0;
return 0;
}
/*************************************************************
Function: RD_read_r
Description:
read data from file to user buffer
Input:
pfile - the target file structure
buffer - the user buffer
size - the size of data to be read
Output:
size of data read from the disk
**************************************************************/
long RD_read_r(struct RD_FILE *pfile, unsigned char *buffer, unsigned long size)
{
struct diskBlock *curBlock;
unsigned char *src;
int found = 0;
long readCount = 0;
long remains;
long curSize;
long i;
struct diskBlock *prevBlock;
// check if the end of the file has already been reached
if (pfile->fpos >= (pfile->dirEntry)->fsize)
{
RDerrno = ERROR_EOF;
return 0;
}
if (pfile->currentBlock == NULL)
{
// there is no current block
curBlock = (pfile->dirEntry)->startBlock;
pfile->blockfpos = 0;
if (curBlock == NULL)
{
// block not found, must be error in file structure
pfile->currentBlock = NULL;
return 0;
}
else
{
pfile->currentBlock = curBlock;
found = 1;
}
}
#ifdef RAMDISK_COMPRESS_USE_ZLIB
else
{
if ((pfile->fpos < pfile->blockfpos) || (pfile->fpos >= pfile->blockfpos + (pfile->currentBlock)->actualSize))
{
// file position will move to another block, compress the current block if necessary
compressCurrentBlock(pfile);
// one less file handle is using this block
(pfile->currentBlock)->userCount--;
}
}
#endif
// there is a current block
curBlock = pfile->currentBlock;
if (RD_checkBlockLocation(curBlock) == -1)
{
// invalid block location
RDerrno = ERROR_FILE_SYSTEM;
return 0;
}
// check if the file position matches this block
if (pfile->fpos < pfile->blockfpos)
{
// file position is before the beginning of the current block
// find the block that is pointed by the file position by going backward
while (curBlock != NULL)
{
curBlock = curBlock->prevBlock;
pfile->blockfpos -= RD_BLOCK_SIZE;
if ((pfile->fpos >= pfile->blockfpos) && (pfile->fpos < pfile->blockfpos + RD_BLOCK_SIZE))
{
found = 1;
break;
}
}
if (curBlock == NULL)
found = 0;
}
else if (pfile->fpos >= pfile->blockfpos + curBlock->actualSize)
{
// file position is behind the current block
// find the block that is pointed by the file position by going forward
while (curBlock != NULL)
{
pfile->blockfpos += RD_BLOCK_SIZE;
curBlock = curBlock->nextBlock;
if ((pfile->fpos >= pfile->blockfpos) && (pfile->fpos < pfile->blockfpos + RD_BLOCK_SIZE))
{
found = 1;
break;
}
}
if (curBlock == NULL)
found = 0;
}
if (found == 1)
{
// a block other than the current block is found
pfile->currentBlock = curBlock;
#ifdef RAMDISK_COMPRESS_USE_ZLIB
// one more file handle is using this block
(pfile->currentBlock)->userCount++;
// uncompress the block if necessary
if (uncompressCurrentBlock(pfile) == -1)
{
pfile->currentBlock = NULL;
pfile->blockfpos = 0;
return 0;
}
curBlock = pfile->currentBlock;
#endif
}
else
{
// no block other than the current block is found
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -