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

📄 ramfs.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef CYGPKG_FS_RAM_SIMPLE    // The data storage in this case consists of a single    // malloced memory block, together with its size.        size_t              datasize;       // size of data block    cyg_uint8           *data;          // malloced data buffer#else    // The data storage in this case consists of arrays of pointers    // to data blocks.     #if CYGNUM_RAMFS_BLOCKS_DIRECT > 0    // Directly accessible blocks from the inode.    ramfs_block         *direct[CYGNUM_RAMFS_BLOCKS_DIRECT];#endif#if  CYGNUM_RAMFS_BLOCKS_INDIRECT1 > 0    // Single level indirection    ramfs_block         **indirect1[CYGNUM_RAMFS_BLOCKS_INDIRECT1];#endif#if  CYGNUM_RAMFS_BLOCKS_INDIRECT2 > 0    // Two level indirection    ramfs_block         ***indirect2[CYGNUM_RAMFS_BLOCKS_INDIRECT2];#endif#endif    };//==========================================================================// Directory entry.// Fixed sized entry containing a fragment of the name of a file/directory.struct ramfs_dirent{    ramfs_node          *node;          // pointer to node    unsigned int        inuse:1,        // entry in use?                        first:1,        // first directory entry fragment?                        last:1,         // last directory entry fragment?                        namelen:8,      // bytes in whole name                        fraglen:8;      // bytes in name fragment    off_t               next;           // offset of next dirent    // Name fragment, fills rest of entry.    char                name[CYGNUM_RAMFS_DIRENT_SIZE-                             sizeof(ramfs_node *)-                             sizeof( cyg_uint32)-                             sizeof(off_t)];};//==========================================================================// Directory search data// Parameters for a directory search. The fields of this structure are// updated as we follow a pathname through the directory tree.struct ramfs_dirsearch{    ramfs_node          *dir;           // directory to search    const char          *path;          // path to follow    ramfs_node          *node;          // Node found    const char          *name;          // last name fragment used    int                 namelen;        // name fragment length    cyg_bool            last;           // last name in path?};typedef struct ramfs_dirsearch ramfs_dirsearch;//==========================================================================// Forward defsstatic int del_direntry( ramfs_node *dir, const char *name, int namelen );//==========================================================================// Block array// This is used for block allocation when malloc is not being used.#ifdef CYGPKG_FS_RAM_BLOCKS_ARRAY# ifdef CYGPKG_FS_RAM_BLOCKS_ARRAY_EXTERN// Array is defined externally with a user-supplied name__externC ramfs_block CYGPKG_FS_RAM_BLOCKS_ARRAY_NAME[CYGNUM_FS_RAM_BLOCKS_ARRAY_SIZE];// Translate into a usable common name#define ramfs_block_array CYGPKG_FS_RAM_BLOCKS_ARRAY_NAME# else// Array is defined herestatic ramfs_block cyg_ramfs_block_array[CYGNUM_FS_RAM_BLOCKS_ARRAY_SIZE];#define ramfs_block_array cyg_ramfs_block_array# endif// Pointer to list of free blocksstatic ramfs_block *block_free_list = NULL;#endif//==========================================================================// Block allocation#ifndef CYGPKG_FS_RAM_SIMPLE// -------------------------------------------------------------------------// block_init()// Initialize the block allocator by chaining them all together on// block_free_list.#ifdef CYGPKG_FS_RAM_BLOCKS_ARRAYstatic void block_init(void){    static cyg_bool initialized = false;    int i;    if( !initialized )    {        for( i = 0; i < CYGNUM_FS_RAM_BLOCKS_ARRAY_SIZE; i++ )        {            ramfs_block *b = &ramfs_block_array[i];            *(ramfs_block **)b = block_free_list;            block_free_list = b;        }        initialized = true;    }}#endif// -------------------------------------------------------------------------// block_alloc()// Allocate a block for data storage.// If we have a block array, just pick the first off the free list.// If we are mallocing, call malloc() to get it.static ramfs_block *block_alloc(void){    ramfs_block *b;#ifdef CYGPKG_FS_RAM_BLOCKS_ARRAY    block_init();       // Check blocks are initialized    // pick first block off free list.    b = block_free_list;    // and advance list    if( b != NULL )        block_free_list = *(ramfs_block **)b;#else    b = malloc(CYGNUM_RAMFS_BLOCK_SIZE);#endif    // Clear the block to zero if it was allocated    if( b != NULL )        memset( b, 0, CYGNUM_RAMFS_BLOCK_SIZE );    return b;}// -------------------------------------------------------------------------// block_free()// Free a block. Depending on the configuration send it back to the// heap or put it back on free list.static void block_free( ramfs_block *b ){#ifdef CYGPKG_FS_RAM_BLOCKS_ARRAY    // Put the block back on the free list        *(ramfs_block **)b = block_free_list;    block_free_list = b;    #else        // Call free() to return it to the memory pool        free( b );#endif}#endif//==========================================================================// Node buffer management// There are two versions of this, one for the _SIMPLE variant and one for// the _BLOCKS variant. In both cases the interface to this code is via the// findbuffer_node() and freebuffer_node() functions.#ifdef CYGPKG_FS_RAM_SIMPLE//==========================================================================// SIMPLE buffer management.// Each node has a data buffer pointer and a size. This buffer is// realloc()ed as needed.// -------------------------------------------------------------------------// findbuffer_node()// return a pointer to the data at the indicated file position, extending// the buffer if required.static int findbuffer_node( ramfs_node  *node,  // node pointer                            off_t pos,          // data position to get                            cyg_uint8 **buffer, // returned buffer pointer                            size_t *size,       // returned buffer size                            cyg_bool alloc)     // extend allocation?{    if( alloc && (pos == node->datasize || node->datasize == 0) )    {        // If we are allowed to alloc new data, and we are at the end of the        // current data allocation, or there is no data present, allocate or        // extend the data buffer.                cyg_uint8 *newdata;                if( node->data == NULL )            newdata = malloc( CYGNUM_RAMFS_REALLOC_INCREMENT );        else            newdata = realloc( node->data, pos+CYGNUM_RAMFS_REALLOC_INCREMENT );                if( newdata == NULL ) return ENOSPC;        else memset( newdata+pos, 0, CYGNUM_RAMFS_REALLOC_INCREMENT );                node->data = newdata;        node->datasize = pos+CYGNUM_RAMFS_REALLOC_INCREMENT;    }    else if( pos > node->datasize )    {        // Indicate end of data.        *size = 0;        return ENOERR;    }    *buffer = node->data+pos;    *size = node->datasize-pos;    return ENOERR;}// -------------------------------------------------------------------------// freebuffer_node()// Empty out the data storage from the node.static int freebuffer_node( ramfs_node *node ){    if( node->data != NULL )    {        free( node->data );    }    node->data = NULL;    node->datasize = 0;    return ENOERR;}//==========================================================================#else//==========================================================================// _BLOCKS storage management.// Data storage in the node is by means of a set of arrays of pointers to// blocks. The first array points directly to the data blocks. Subsequent// arrays point to single and double indirect blocks respectively. // -------------------------------------------------------------------------// findbuffer_direct()// Indexes into an array of block pointers and extracts a pointer to the// data at offset _pos_, allocating new blocks if required.static int findbuffer_direct( off_t pos,                              ramfs_block **blocks,                              int nblocks,                              cyg_uint8 **buffer,                              size_t *size,                              cyg_bool alloc){    int bi = pos / CYGNUM_RAMFS_BLOCK_SIZE;    int bpos = pos % CYGNUM_RAMFS_BLOCK_SIZE;    ramfs_block *b;        *buffer = NULL;    *size = 0;        if( bi >= nblocks )        return ENOERR;    b = blocks[bi];    if( b == NULL )    {        // There is no block there. If _alloc_ is true we can fill the        // slot in with a new block. If it is false, we indicate end of        // data with a zero size result.        if( alloc )        {            b = block_alloc();            if( b == NULL )                return ENOSPC;            blocks[bi] = b;        }        else return ENOERR;    }    *buffer = &((*b)[bpos]);    *size = CYGNUM_RAMFS_BLOCK_SIZE - bpos;    return ENOERR;}// -------------------------------------------------------------------------// findbuffer_indirect1()// Indexes into an array of pointers to blocks containing pointers to// blocks and extracts a pointer to the data at offset _pos_,// allocating new blocks if required.#if CYGNUM_RAMFS_BLOCKS_INDIRECT1 > 0static int findbuffer_indirect1( off_t pos,                                 ramfs_block ***blocks,                                 int nblocks,                                 cyg_uint8 **buffer,                                 size_t *size,                                 cyg_bool alloc){    int bi = pos / RAMFS_INDIRECT1_BLOCK_EXTENT;    int bpos = pos % RAMFS_INDIRECT1_BLOCK_EXTENT;    int err;    cyg_uint8 *b;    size_t sz;    // Use findbuffer_direct() to index and allocate    // the first level indirect block.        err = findbuffer_direct( bi*CYGNUM_RAMFS_BLOCK_SIZE,                             (ramfs_block **)blocks,                             nblocks,                             &b,                             &sz,                             alloc);    if( err != ENOERR )        return err;    if( sz == 0 )    {        *size = 0;        return ENOERR;    }    // Use findbuffer_direct() on the first level indirect    // block to allocate and return the data pointer.        return findbuffer_direct( bpos,                              blocks[bi],                              RAMFS_INDIRECT_PER_BLOCK,                              buffer,                              size,                              alloc);}#endif// -------------------------------------------------------------------------// findbuffer_indirect1()// Indexes into an array of pointers to blocks containing pointers to// blocks containing pointers to blocks (!) and extracts a pointer to// the data at offset _pos_, allocating new blocks if required.#if CYGNUM_RAMFS_BLOCKS_INDIRECT2 > 0static int findbuffer_indirect2( off_t pos,                                 ramfs_block ****blocks,                                 int nblocks,                                 cyg_uint8 **buffer,                                 size_t *size,                                 cyg_bool alloc){    int bi = pos / RAMFS_INDIRECT2_BLOCK_EXTENT;    int bpos = pos % RAMFS_INDIRECT2_BLOCK_EXTENT;    int err;    cyg_uint8 *b;    size_t sz;    // Use findbuffer_direct() to index and allocate    // the first level indirect block.    err = findbuffer_direct( bi*CYGNUM_RAMFS_BLOCK_SIZE,                             (ramfs_block **)blocks,                             nblocks,                             &b,                             &sz,                             alloc);    if( err != ENOERR )        return err;    if( sz == 0 )    {        *size = 0;        return ENOERR;    }    // Use findbuffer_indirect1() on the first level indirect block to    // index and allocate the next level indirect block and the data    // block.        return findbuffer_indirect1( bpos,                                 blocks[bi],                                 RAMFS_INDIRECT_PER_BLOCK,                                 buffer,                                 size,                                 alloc);}#endif// -------------------------------------------------------------------------// findbuffer_node()// Depending on the offset and configuration, call the appropriate// function to get the buffer pointer.static int findbuffer_node( ramfs_node  *node,

⌨️ 快捷键说明

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