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

📄 block.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
字号:
/*
* EBS - RTFS (Real Time File Manager)
*
* Copyright EBS Inc. 1996
* All rights reserved.
* This code may not be redistributed in source or linkable object form
* without the consent of its author.
*/
/* BLOCK.C - Directory block buffering routines
    
    Block buffers contain a data block a DDRIVE pointer and a block number.
    If the DDRIVE pointer is Non Null the data is valid for the block.
    Blocks have three states.
        Unused  - May be grabbed to use on a block. (PDRIVE == NULL)
        Open    - May not be re-used until the routine using it lets go
        Closed  - Data is valid in the buffer but no one is using it. 
                    if there are no Unused blocks this one may be used.
                    But if someone needs the data in here it will be re-opened
                    and used.           

    Routines in this file include:

    pc_alloc_blk    -   Internal to this file. 
    pc_blkpool      -   Internal to this file. 
    pc_free_all_blk -   Release all buffers associated with a drive
    pc_free_buf -   Release a single buffer for possible re-use

    pc_init_blk -   Initialize a buffer's drive and block #s. Zero its
                        data buffer
    pc_read_blk -   Read data from disk into a buffer
    pc_write_blk    -   Write data from the buffer to the disk.
    pc_scratch_blk  -   Allocate a block to use as a scratch buffer
*/

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif


RTFS_FILE(allocblk.c, pc_alloc_blk)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif

/******************************************************************************
    PC_ALLOC_BLK - Find existing or create an empty block in the buffer pool.

Description
    Use pdrive and blockno to search for a buffer in the buffer pool.
    If not found create a new buffer entry by discarding the Least recently
    used buffer in the buffer pool. The buffer is locked in core. A pointer to
    the buffer is returned in ppblk. If all buffers are in use it returns 
    NULL in *ppblk.

 Returns
    Returns TRUE if the buffer was found in the pool or FALSE if a new
    buffer was assigned.
*****************************************************************************/

extern dword  useindex;         /* See bss.c */

/* This function is used only by functions in this file */
BOOLEAN pc_alloc_blk(BLKBUFF **ppblk, DDRIVE *pdrive, BLOCKT blockno)   /*__fn__*/
{
    BLKBUFF *pblk;
    BLKBUFF *oldest = 0;
    BLKBUFF *freeblk = 0;
    dword lru = (dword) ~0L;

    /* Get or init the block pool */
    pblk = pc_blkpool(pdrive); 

    OS_CLAIM_FSCRITICAL()
    useindex += 1;
    while (pblk)
    {
        if (!pblk->pdrive)
        {
            /* This buffer's free */
            freeblk = pblk;         /* BUG FIX */
        }
        else
        {
            if ( (pblk->pdrive == pdrive) && (pblk->blockno == blockno)  )
            {
                /* Found it */
                *ppblk = pblk;
                /* Update the last recently used stuf */
                pblk->lru = useindex;
                pblk->use_count += 1;
                OS_RELEASE_FSCRITICAL()
                return(TRUE);
            }
            else
            {
                /* No match. see if its a candidate for swapping if we run out of
                    pointers */
                if (!pblk->use_count)
                {
                    if (pblk->lru < lru)
                    {
                        lru = pblk->lru;
                        oldest = pblk;
                    }
                }
            }
        }
        pblk = pblk->pnext;
    }

    /* If off the end of the list we have to bump somebody */
    if (freeblk)
        pblk = freeblk;
    else
        pblk = oldest;


    if (!pblk)
    {
        OS_RELEASE_FSCRITICAL()
        pc_report_error(PCERR_BLOCKCLAIM);
        /* Panic */
        *ppblk = 0;
        return(FALSE);
    }

    pblk->lru = useindex;
    pblk->pdrive = pdrive;
    pblk->blockno = blockno;
    pblk->use_count = 1;

    OS_RELEASE_FSCRITICAL()
    *ppblk = pblk;
    /* Return FALSE since we didn't find it in the buffer pool */
    return (FALSE);
}

RTFS_FILE(blkpool.c, pc_blkpool)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
 
/****************************************************************************
    PC_BLKBOOLEAN - Return the first element in a drives buffer pool

Description
    Return the beginning of the buffer pool for a drive. If the pool
    is uninitialized report it. The buffer pool should have been 
    initialized in pc_memory_init.

 Returns
    Returns the beginning of the buffer pool or NULL if pc_memory_init was
    not first called.

****************************************************************************/

/* Return the beginning of the buffer pool. Report an error if not already 
    initialized */
BLKBUFF *pc_blkpool(DDRIVE *pdrive)                             /*__fn__*/
{
    ARGSUSED_PVOID(pdrive);
    return(mem_block_pool);
}

RTFS_FILE(frealblk.c, pc_free_all_blk)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif

/****************************************************************************
    PC_FREE_ALL_BLK - Release all buffers associated with a drive

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.

 Returns
    Nothing
****************************************************************************/
 
void pc_free_all_blk(DDRIVE *pdrive)                                /*__fn__*/
{
    BLKBUFF *pblk;

    /* Get or init the block pool */
    pblk = pc_blkpool(pdrive); 

    OS_CLAIM_FSCRITICAL()
    while (pblk)
    {
        if (pblk->pdrive == pdrive)
        {
            if (pblk->use_count)
                pc_report_error(PCERR_BLOCKLOCK);
            pblk->use_count = 0;
            pblk->pdrive = 0;
        }
        pblk = pblk->pnext;
    }
    OS_RELEASE_FSCRITICAL()

}

RTFS_FILE(freebuf.c, pc_free_buf)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif

/*****************************************************************************
    PC_FREE_BUF - Unlock a block buffer.

Description
    Give back a buffer to the system buffer pool so that it may
    be re-used. If was_err is TRUE this means that the data in the 
    buffer is invalid so discard the buffer from the buffer pool.

    
 Returns
    Nothing

***************************************************************************/

/* Free a buffer by unlocking it. If waserr is true, zero out the  
    drive number so the erroneous data is not cached. */
void pc_free_buf(BLKBUFF *pblk, BOOLEAN waserr)                     /*__fn__*/
{
    OS_CLAIM_FSCRITICAL()
    if (pblk)
    {
        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 = 0;
    }
    OS_RELEASE_FSCRITICAL()
}

RTFS_FILE(initblk.c, pc_init_blk)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
#if (RTFS_WRITE)
#if (RTFS_SUBDIRS)
/***************************************************************************
    PC_INIT_BLK - Zero a BLKBUFF and add it to the buffer pool
Description
    Allocate and zero a BLKBUFF and add it to the to the buffer pool.

    Note: After initializing you "own" the buffer. You must release it by
    calling pc_free_buff() before it may be used for other blocks.

 Returns
    Returns a valid pointer or NULL if no core.

****************************************************************************/

BLKBUFF *pc_init_blk(DDRIVE *pdrive, BLOCKT blockno)                /*__fn__*/
{
    BLKBUFF *pblk;

    if ( !pdrive || (blockno >= pdrive->numsecs) )
        return(0);
    else
    {
        pc_alloc_blk(&pblk, pdrive , blockno );
        if (pblk)
            pc_memfill(pblk->data, 512, '\0');
        return (pblk);
    }
}
#endif
#endif
RTFS_FILE(readblk.c, pc_read_blk)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif

/****************************************************************************
    PC_READ_BLK - Allocate and read a BLKBUFF, or get it from the buffer pool.

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.

 Returns
    Returns a valid pointer or NULL if block not found and not readable.

*****************************************************************************/

BLKBUFF *pc_read_blk(DDRIVE *pdrive, BLOCKT blockno)                /*__fn__*/
{
    BLKBUFF *pblk;
    BOOLEAN found_buffer;

    if ( !pdrive || (blockno >= pdrive->numsecs) )
        return(0);

    found_buffer = pc_alloc_blk(&pblk, pdrive , blockno);

    if (pblk)
    {
        if (!found_buffer)
        {
            /* We allocated a buffer but it doesn't have valid data 
                read it in. If the read fails throw the buffer away */
            if (!devio_read(pdrive->driveno,  blockno, pblk->data, (int) 1, FALSE))
            {
                /* oops: Error, Discard the buffer */
                pc_free_buf(pblk, TRUE);
                pblk = 0;
            }
        }
    }
    return(pblk);
}


RTFS_FILE(writblk.c, pc_write_blk)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
#if (RTFS_WRITE)

/***************************************************************************
    PC_WRITE_BLK - Flush a BLKBUFF to disk.
Description
    Use pdrive and blockno information in pblk to flush it's data buffer
    to disk.

 Returns
    Returns TRUE if the write succeeded.
****************************************************************************/

/* Write */
BOOLEAN pc_write_blk(BLKBUFF *pblk)                                 /*__fn__*/
{
    BOOLEAN ret_val;

    if (!pblk || !pblk->pdrive)
    {
        return(FALSE);
    }
    ret_val = devio_write(pblk->pdrive->driveno,pblk->blockno, pblk->data, (int) 1, FALSE);
    return(ret_val);
}
#endif



RTFS_FILE(scrtchblk.c, pc_scratch_blk)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif

/***************************************************************************
    PC_SCRATCH_BLK - Return a block for scratch purposes.
Description
    Use the block buffer pool as a heap of 512 byte memory locations
    When done call void pc_free_buf(pblk, TRUE) to clean up

 Returns
    Returns a blkbuf if one is available or NULL
****************************************************************************/
extern DDRIVE *scratch_pdrive;  /* See bss.c */

/* Write */
BLKBUFF *pc_scratch_blk(void)                                   /*__fn__*/
{
    BLKBUFF *pblk;
    OS_CLAIM_FSCRITICAL()
    scratch_pdrive++;  /* We want a unique number for the alloc routine */
    OS_RELEASE_FSCRITICAL()
    pc_alloc_blk(&pblk, scratch_pdrive, BLOCKEQ0);
    return (pblk);
}


⌨️ 快捷键说明

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