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

📄 ramfs.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 5 页
字号:
//==========================================================================////      ramfs.c////      RAM file system////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):           nickg// Contributors:        nickg// Date:                2000-07-25// Purpose:             RAM file system// Description:         This is a RAM filesystem for eCos. It attempts to//                      provide full POSIX-compatible filesystem behaviour//                      while at the same time being efficient in terms of//                      time and space used.//                      ////####DESCRIPTIONEND####////==========================================================================// // General Description// ===================// // This is an implementation of a RAM filesystem for eCos. Its goal is// to provide a working example of a filesystem that provides most of// the required POSIX functionality. And obviously it may also be// useful in its own right.////// Nodes// -----//// All files and directories are represented by node objects. Each// ramfs_node structure contains the following fields://// mode   - Node type, file or directory.// refcnt - Number of references to this node. For files each open counts as//          a reference and for directories a node is referenced when it is made//          current directory, or is opened for reading.// nlink  - Number of links to this node. Each directory entry that references//          this node is a link. // size   - Size of the data in this node in bytes.// atime  - Last time this node was accessed.// mtime  - Last time the data in this node was modified.// ctime  - Last time the status information in this node was changed.//// The data storage in a node is controlled by the configuration and// can take two forms. These will be described later.//          // Directories// -----------//// A directory is a node whose data is a list of directory entries. To// simplify management of these, long directory entries are split into// a chain of fixed size ramfs_dirent structures. These contain the// following fields://// node    - Pointer to node referenced by this entry. This is present in//           every directory entry fragment// inuse   - Set to 1 if this entry is in use, zero if it is free.// first   - Set to 1 if this is the first fragment of a directory entry.// last    - Set to 1 if this is the last fragment of a directory entry.// namelen - The size of the whole file name.// fraglen - The number of bytes of the file name that are stored in this//           fragment.// next    - The offset of the next fragment of this directory entry.// name    - The characters of the fragment of the file name stored in this//           entry.//// Small file names are stored in a single fragment. Longer names are// stored in a chain of fragments.//// Data Storage// ------------//// Two data storage mechanisms may be configured, the SIMPLE and the// BLOCKS mechanisms.//// SIMPLE Data Storage// ~~~~~~~~~~~~~~~~~~~//// This mechanism simply uses malloc() and free() to allocate the// memory for both nodes and file data. File data is stored in a// single malloced vector that is realloced as necessary to acquire// more space. //// The advantage of this approach is that the RAM filesystem only uses// as much memory as it needs, the rest is available for use by other// components. It also requires much simpler data structures and code// in the filesystem to manage. However, if any files get to be a// significant proportion of the size of the heap, there is the danger// that fragmentation will prevent any further extension of some// files, even if there is enough memory in total. It also requires an// implementation of malloc() to be present. If this needs to be// present for other components,then this is not a significant// overhead, but including it just for use by this filesystem// represents a major addition of code and data structures.////// BLOCKS Data Storage// ~~~~~~~~~~~~~~~~~~~//// This mechanism divides the memory used for file storage into fixed// sized blocks. These blocks may either be allocated using// malloc()/free(), or may be obtained from a array of blocks reserved// for the purpose. Configuration allows the block size to be// selected, as well as the allocation mechanism, and in the case of a// block array, whether it is defined here or by an external// component.// // Data storage in nodes is arranges in three arrays of pointers to// blocks. The first array points directly to data blocks, the second// to blocks which themselves contain pointers to data blocks, and the// third to blocks which contain pointers to blocks which contain// pointers to data blocks. In the default configuration These last// two arrays have only one element each.// // The following shows how the data is arranged in a fully populated// file with a 256 byte block size using the default configuration.// //      Node// ~            ~// |            |// |            |// +------------+// |     *------+--------> data block 0// +------------+// |     *------+--------> data block 1// +------------+// |     *------+--------> data block 2// +------------+// |     *------+--------> data block 3// +------------+// |     *------+--------> data block 4// +------------+// |     *------+--------> data block 5// +------------+// |     *------+--------> data block 6// +------------+// |     *------+--------> data block 7// +------------+// |     *------+--------> +------------+// +------------+          |     *------+--------> data block 8// |     *------+----+     +------------+// +------------+    |     |            |//                   |     ~            ~//                   |     |            |//                   |     +------------+//                   |     |     *------+--------> data block 71//                   |     +------------+//                   |     //                   +---->+------------+         +------------+//                         |     *------+-------->|     *------+---->data block 72//                         +------------+         +------------+//                         |            |         |            |//                         ~            ~         ~            ~//                         |            |         |            |//                         +------------+         +------------+//                         |     *------+---+     |     *------+----> data block 135//                         +------------+   |     +------------+//                                          |//                                          |     +------------+//                                          +---->|     *------+----> data block 4104//                                                +------------+//                                                |            |//                                                ~            ~//                                                |            |//                                                +------------+//                                                |     *------+----> data block 4167//                                                +------------+// // //// The advantages of this approach are that, first, memory usage is// divided into discreet fixed size blocks which are easier to// manage. When using malloc() to allocate them, they will fit into// any free memory of at least the right size. Using the block array// option removes the need to have a malloc() implementation at all.//// The disadvantages of this mechanism are that, first, when using// malloc() to allocate blocks, the per-block memory allocator// overhead is paid for each block, rather than per file. This may// result in less memory overall being available for data// storage. When using the block array, it is permanently reserved for// use by the ram filesystem, and is not available for use by other// components.////==========================================================================#include <pkgconf/system.h>#include <pkgconf/hal.h>#include <pkgconf/kernel.h>#include <pkgconf/io_fileio.h>#include <pkgconf/fs_ram.h>#include <cyg/kernel/ktypes.h>         // base kernel types#include <cyg/infra/cyg_trac.h>        // tracing macros#include <cyg/infra/cyg_ass.h>         // assertion macros#include <unistd.h>#include <sys/types.h>#include <fcntl.h>#include <sys/stat.h>#include <errno.h>#include <dirent.h>#include <stdlib.h>#include <string.h>#include <cyg/fileio/fileio.h>#include <cyg/kernel/kapi.h>#include <cyg/infra/diag.h>//==========================================================================// Sizes derived from configuration// -------------------------------------------------------------------------// Simple malloc based allocator parameters#ifdef CYGPKG_FS_RAM_SIMPLE#define RAMFS_FILESIZE_MAX      UINT_MAX#else// -------------------------------------------------------------------------// Block allocator parameters// The number of nodes per block#define RAMFS_NODES_PER_BLOCK (CYGNUM_RAMFS_BLOCK_SIZE/sizeof(ramfs_node))// The number of indirect pointers that can be stored in a single data block#define RAMFS_INDIRECT_PER_BLOCK (CYGNUM_RAMFS_BLOCK_SIZE/sizeof(ramfs_block *))// The number of directory entries that can be stored in a single data block#define RAMFS_DIRENT_PER_BLOCK  (CYGNUM_RAMFS_BLOCK_SIZE/sizeof(ramfs_dirent))// Number of bytes contained in a one level indirect block#define RAMFS_INDIRECT1_BLOCK_EXTENT (RAMFS_INDIRECT_PER_BLOCK* \                                      CYGNUM_RAMFS_BLOCK_SIZE)// number of bytes contained in a two level indirect block#define RAMFS_INDIRECT2_BLOCK_EXTENT (RAMFS_INDIRECT_PER_BLOCK* \                                      RAMFS_INDIRECT_PER_BLOCK* \                                      CYGNUM_RAMFS_BLOCK_SIZE)// The maximum data offset for data directly accessed from the node#define RAMFS_DIRECT_MAX        (CYGNUM_RAMFS_BLOCKS_DIRECT*CYGNUM_RAMFS_BLOCK_SIZE)// The maximum data offset for data accessed from the single level indirect blocks#define RAMFS_INDIRECT1_MAX     (RAMFS_DIRECT_MAX+                      \                                 (CYGNUM_RAMFS_BLOCKS_INDIRECT1*        \                                  RAMFS_INDIRECT1_BLOCK_EXTENT))// The maximum data offset for data accessed from the two level indirect blocks#define RAMFS_INDIRECT2_MAX     (RAMFS_INDIRECT1_MAX+                   \                                 (CYGNUM_RAMFS_BLOCKS_INDIRECT2*        \                                  RAMFS_INDIRECT2_BLOCK_EXTENT))// The maximum size of a file#define RAMFS_FILESIZE_MAX      RAMFS_INDIRECT2_MAX#endif//==========================================================================// Forward definitions// Filesystem operationsstatic int ramfs_mount    ( cyg_fstab_entry *fste, cyg_mtab_entry *mte );static int ramfs_umount   ( cyg_mtab_entry *mte );static int ramfs_open     ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             int mode,  cyg_file *fte );static int ramfs_unlink   ( cyg_mtab_entry *mte, cyg_dir dir, const char *name );static int ramfs_mkdir    ( cyg_mtab_entry *mte, cyg_dir dir, const char *name );static int ramfs_rmdir    ( cyg_mtab_entry *mte, cyg_dir dir, const char *name );static int ramfs_rename   ( cyg_mtab_entry *mte, cyg_dir dir1, const char *name1,                             cyg_dir dir2, const char *name2 );static int ramfs_link     ( cyg_mtab_entry *mte, cyg_dir dir1, const char *name1,                             cyg_dir dir2, const char *name2, int type );static int ramfs_opendir  ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             cyg_file *fte );static int ramfs_chdir    ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             cyg_dir *dir_out );static int ramfs_stat     ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             struct stat *buf);static int ramfs_getinfo  ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             int key, void *buf, int len );static int ramfs_setinfo  ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             int key, void *buf, int len );// File operationsstatic int ramfs_fo_read      (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);static int ramfs_fo_write     (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);static int ramfs_fo_lseek     (struct CYG_FILE_TAG *fp, off_t *pos, int whence );static int ramfs_fo_ioctl     (struct CYG_FILE_TAG *fp, CYG_ADDRWORD com,                                CYG_ADDRWORD data);static int ramfs_fo_fsync     (struct CYG_FILE_TAG *fp, int mode );        static int ramfs_fo_close     (struct CYG_FILE_TAG *fp);static int ramfs_fo_fstat     (struct CYG_FILE_TAG *fp, struct stat *buf );static int ramfs_fo_getinfo   (struct CYG_FILE_TAG *fp, int key, void *buf, int len );static int ramfs_fo_setinfo   (struct CYG_FILE_TAG *fp, int key, void *buf, int len );// Directory operationsstatic int ramfs_fo_dirread      (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);static int ramfs_fo_dirlseek     (struct CYG_FILE_TAG *fp, off_t *pos, int whence );//==========================================================================// Filesystem table entries// -------------------------------------------------------------------------// Fstab entry.// This defines the entry in the filesystem table.// For simplicity we use _FILESYSTEM synchronization for all accesses since// we should never block in any filesystem operations.FSTAB_ENTRY( ramfs_fste, "ramfs", 0,             CYG_SYNCMODE_FILE_FILESYSTEM|CYG_SYNCMODE_IO_FILESYSTEM,             ramfs_mount,             ramfs_umount,             ramfs_open,             ramfs_unlink,             ramfs_mkdir,             ramfs_rmdir,             ramfs_rename,             ramfs_link,             ramfs_opendir,             ramfs_chdir,             ramfs_stat,             ramfs_getinfo,             ramfs_setinfo);// -------------------------------------------------------------------------// File operations.// This set of file operations are used for normal open files.static cyg_fileops ramfs_fileops ={    ramfs_fo_read,    ramfs_fo_write,    ramfs_fo_lseek,    ramfs_fo_ioctl,    cyg_fileio_seltrue,    ramfs_fo_fsync,    ramfs_fo_close,    ramfs_fo_fstat,    ramfs_fo_getinfo,    ramfs_fo_setinfo};// -------------------------------------------------------------------------// Directory file operations.// This set of operations are used for open directories. Most entries// point to error-returning stub functions. Only the read, lseek and// close entries are functional.static cyg_fileops ramfs_dirops ={    ramfs_fo_dirread,    (cyg_fileop_write *)cyg_fileio_enosys,    ramfs_fo_dirlseek,    (cyg_fileop_ioctl *)cyg_fileio_enosys,    cyg_fileio_seltrue,    (cyg_fileop_fsync *)cyg_fileio_enosys,    ramfs_fo_close,    (cyg_fileop_fstat *)cyg_fileio_enosys,    (cyg_fileop_getinfo *)cyg_fileio_enosys,    (cyg_fileop_setinfo *)cyg_fileio_enosys};//==========================================================================// Data typedefs// Some forward typedefs for the main data structures.struct ramfs_node;typedef struct ramfs_node ramfs_node;struct ramfs_dirent;typedef struct ramfs_dirent ramfs_dirent;#ifndef CYGPKG_FS_RAM_SIMPLEtypedef cyg_uint8 ramfs_block[CYGNUM_RAMFS_BLOCK_SIZE];#endif//==========================================================================// File and directory node// This data structure represents a file or directory.struct ramfs_node{    mode_t              mode;           // node type    cyg_ucount32        refcnt;         // open file/current dir references    nlink_t             nlink;          // number of links to this node    size_t              size;           // size of file in bytes    time_t              atime;          // last access time    time_t              mtime;          // last modified time    time_t              ctime;          // last changed status time

⌨️ 快捷键说明

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