📄 ramfs.c
字号:
//==========================================================================//// 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 + -