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

📄 block.c

📁 NUcleus plus 支持的文件系统。 是学习文件系统的很好参考资料。
💻 C
📖 第 1 页 / 共 2 页
字号:
* 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 + -