📄 block.c
字号:
* DESCRIPTION
*
* Use pdrive to find all buffers in the buffer pool associated
* with the drive. Mark them as unused, called by dsk_close.
* If any are locked, print a debug message in debug mode to warn
* the programmer.
*
* AUTHOR
*
* Takahiro Takahashi
*
* INPUTS
*
* pdrive Drive management structure.
*
* OUTPUTS
*
* None.
*
*************************************************************************/
VOID pc_free_all_blk(DDRIVE *pdrive)
{
BLKBUFF *pblk;
/* Get or init the block pool */
pblk = pc_blkpool(pdrive);
while (pblk)
{
/* If this block has specified drive's data */
if (pblk->pdrive == pdrive)
{
/* If someone is using this block, report error for debugging. */
if (pblk->use_count)
pc_report_error(PCERR_BLOCKLOCK);
pc_free_buf(pblk, YES);
}
pblk = pblk->pnext;
}
}
/************************************************************************
* FUNCTION
*
* pc_free_buf
*
* DESCRIPTION
*
* Give back a buffer to the system buffer pool so that it may be
* re-used. If was_err is YES this means that the data in the
* buffer is invalid so discard the buffer from the buffer pool.
*
* AUTHOR
*
* Takahiro Takahashi
*
* INPUTS
*
* pblk Block pointer to be freed.
* waserr If it 0, the cache is
* discarded.
*
* OUTPUTS
*
* None.
*
*************************************************************************/
VOID pc_free_buf(BLKBUFF *pblk, INT waserr)
{
if (pblk)
{
#ifdef DEBUG3
DEBUG_PRINT("Free block %d\n", pblk->blockno);
#endif
if (pblk->use_count)
pblk->use_count -= 1;
/* If the buffer is corrupted we null the buffer. This is safe even
in a multitasking environment because the region of the disk
containing the block is always locked exclusively when buffer
writes are taking place */
if (waserr)
pblk->pdrive = NULL;
}
}
/************************************************************************
* FUNCTION
*
* pc_read_blk
*
* DESCRIPTION
*
* Use pdrive and blockno to determine what block to read. Read
* the block or get it from the buffer pool and return the buffer.
*
* Note: After reading, you "own" the buffer. You must release it
* by calling pc_free_buff() before it may be used for other
* blocks.
*
* AUTHOR
*
* Takahiro Takahashi
*
* INPUTS
*
* pblk Read block buffer.
* pdriver Pointer to DDRIVE structure.
* blockno Block number to read
*
* OUTPUTS
*
* NU_SUCCESS If service is successful.
* NUF_NO_BLOCK No block buffer available.
* NUF_IO_ERROR Driver IO error.
* NUF_INTERNAL Nucleus FILE internal error.
*
*************************************************************************/
STATUS pc_read_blk(BLKBUFF **pblk, DDRIVE *pdrive, UINT32 blockno)
{
INT found_buffer;
STATUS ret_status;
if ( !pdrive || (blockno >= pdrive->numsecs) )
return(NUF_INTERNAL);
found_buffer = pc_alloc_blk(pblk, pdrive, blockno);
if (found_buffer < 0)
return(found_buffer); /* Internal error */
if (found_buffer)
{
/* If the block is being read we loop until the io_pending
condition is gone. */
#if (LOCK_METHOD == 2)
while ((*pblk)->io_pending)
{
fs_release();
fs_suspend_task();
fs_reclaim();
}
#endif
ret_status = NU_SUCCESS;
}
else
{
/* Not found. Read it in */
(*pblk)->io_pending = YES;
PC_DRIVE_IO_ENTER(pdrive->driveno)
if ( !pc_bdevsw[pdrive->driveno].io_proc(pdrive->driveno, blockno, (*pblk)->data, (UINT16) 1, YES) )
{
/* oops: Drop the use count and mark an error.
if anybody else is waiting do a wakeup */
(*pblk)->use_count = 0;
/* Now the block doesn't exist in the buffer pool */
(*pblk)->pdrive = NULL;
ret_status = NUF_IO_ERROR;
}
else
{
/* The read worked */
ret_status = NU_SUCCESS;
}
(*pblk)->io_pending = NO;
PC_DRIVE_IO_EXIT(pdrive->driveno)
}
return(ret_status);
}
/************************************************************************
* FUNCTION
*
* pc_write_blk
*
* DESCRIPTION
*
* Use pdrive and blockno information in pblk to flush it's data
* buffer to disk.
*
* AUTHOR
*
* Takahiro Takahashi
*
*
* INPUTS
*
* pblk Write block buffer.
*
* OUTPUTS
*
* NU_SUCCESS If the write succeeded.
* NUF_IO_ERROR Driver IO error.
* NUF_INTERNAL Nucleus FILE internal error.
*
*************************************************************************/
STATUS pc_write_blk(BLKBUFF *pblk)
{
INT ret_val = NU_SUCCESS;
if ( !pblk || !pblk->pdrive )
return(NUF_INTERNAL);
PC_DRIVE_IO_ENTER(pblk->pdrive->driveno)
if ( !pc_bdevsw[pblk->pdrive->driveno].io_proc(pblk->pdrive->driveno,
pblk->blockno, pblk->data, (UINT16) 1, NO) )
{
ret_val = NUF_IO_ERROR;
}
PC_DRIVE_IO_EXIT(pblk->pdrive->driveno)
return(ret_val);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -