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

📄 fileio.sgml

📁 eCos操作系统源码
💻 SGML
📖 第 1 页 / 共 3 页
字号:
<para>The <structfield>f_ops</structfield> field contains a pointer to atable of file I/O operations. This has the following structure:</para><programlisting>struct CYG_FILEOPS_TAG{        int	(*fo_read)      (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);        int	(*fo_write)     (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);        int     (*fo_lseek)     (struct CYG_FILE_TAG *fp, off_t *pos, int whence );        int	(*fo_ioctl)     (struct CYG_FILE_TAG *fp, CYG_ADDRWORD com,                                 CYG_ADDRWORD data);        int	(*fo_select)    (struct CYG_FILE_TAG *fp, int which, CYG_ADDRWORD info);        int     (*fo_fsync)     (struct CYG_FILE_TAG *fp, int mode );                int	(*fo_close)     (struct CYG_FILE_TAG *fp);        int     (*fo_fstat)     (struct CYG_FILE_TAG *fp, struct stat *buf );        int     (*fo_getinfo)   (struct CYG_FILE_TAG *fp, int key, char *buf, int len );        int     (*fo_setinfo)   (struct CYG_FILE_TAG *fp, int key, char *buf, int len );};</programlisting><para>It should be obvious from the names of most of these functions whattheir responsibilities are. The <function>fo_getinfo()</function>and <function>fo_setinfo()</function> function pointers, like theircounterparts in the filesystem structure, implement minor control andinfo functions such as <function>fpathconf()</function>.</para><para>The second argument to the <function>fo_read()</function> and<function>fo_write()</function> function pointers is a pointer to aUIO structure:</para><programlisting>struct CYG_UIO_TAG{    struct CYG_IOVEC_TAG *uio_iov;	/* pointer to array of iovecs */    int	                 uio_iovcnt;	/* number of iovecs in array */    off_t       	 uio_offset;	/* offset into file this uio corresponds to */    ssize_t     	 uio_resid;	/* residual i/o count */    enum cyg_uio_seg     uio_segflg;    /* see above */    enum cyg_uio_rw      uio_rw;        /* see above */};struct CYG_IOVEC_TAG{    void           *iov_base;           /* Base address. */    ssize_t        iov_len;             /* Length. */};</programlisting><para>This structure encapsulates the parameters of any data transferoperation. It provides support for scatter/gather operations andrecords the progress of any data transfer. It is also compatible withthe I/O operations of any BSD-derived network stacks and filesystems.</para><para>When a file is opened (or a file object created by some other means,such as <function>socket()</function> or <function>accept()</function>) it is theresponsibility of the filesystem open operation to initialize all thefields of the object except the <structfield>f_ucount</structfield>,<structfield>f_syncmode</structfield> and<structfield>f_mte</structfield> fields. Since the<structfield>f_flag</structfield> field will already contain bits belonging to the FILEIOinfrastructure, any changes to it must be made with the appropriatelogical operations.</para></chapter><!-- }}} --><!-- {{{ Directories --><chapter id="fileio-directories"><title>Directories</title><para>Filesystem operations all take a directory pointer as one of theirarguments.  A directory pointer is an opaque handle managed by thefilesystem. It should encapsulate a reference to a specific directorywithin the filesystem. For example, it may be a pointer to the datastructure that represents that directory (such as an inode), or apointer to a pathname for the directory.</para><para>The <function>chdir()</function> filesystem function pointer has twomodes of use. When passed a pointer in the<parameter>dir_out</parameter> argument, it should locate the nameddirectory and place a directory pointer there. If the<parameter>dir_out</parameter> argument is NULL then the<parameter>dir</parameter> argument is a previously generateddirectory pointer that can now be disposed of. When the infrastructureis implementing the <function>chdir()</function> function it makes twocalls to filesystem <function>chdir()</function> functions. The firstis to get a directory pointer for the new current directory. If thissucceeds the second is to dispose of the old current directorypointer.</para><para>The <function>opendir()</function> function is used to open adirectory for reading. This results in an open file object that can beread to return a sequence of <structname>struct dirent</structname>objects. The only operations that are allowed on this file are<function>read</function>, <function>lseek</function> and<function>close</function>. Each read operation on this file shouldreturn a single <structname>struct dirent</structname> object. Whenthe end of the directory is reached, zero should be returned. The onlyseek operation allowed is a rewind to the start of the directory, bysupplying an offset of zero and a <parameter>whence</parameter>specifier of <literal>SEEK_SET</literal>.</para><para>Most of these considerations are invisible to clients of a filesystemsince they will access directories via the POSIX<function>opendir()</function>, <function>readdir()</function> and<function>closedir()</function> functions.</para><para>Support for the <function>getcwd()</function> function is provided bythree mechanisms.  The first is to use the<literal>FS_INFO_GETCWD</literal> getinfo key on the filesystem to useany internal support that it has for this. If that fails it falls backon one of the two other mechanisms. If<literal>CYGPKG_IO_FILEIO_TRACK_CWD</literal> is set then the currentdirectory is tracked textually in <function>chdir()</function> and the result of that isreported in getcwd(). Otherwise an attempt is made to traverse thedirectory tree to its root using &quot;..&quot; entries.</para><para>This last option is complicated and expensive, and relies on thefilesystem supporting &quot;.&quot; and &quot;..&quot;  entries. This is not always thecase, particularly if the filesystem has been ported from anon-UNIX-compatible source. Tracking the pathname textually willusually work, but might not produce optimum results when symboliclinks are being used.</para></chapter><!-- }}} --><!-- {{{ Synchronization --><chapter id="fileio-synchronization"><title>Synchronization</title><para>The FILEIO infrastructure provides a synchronization mechanism forcontrolling concurrent access to filesystems. This allows existingfilesystems to be ported to eCos, even if they do not have their ownsynchronization mechanisms. It also allows new filesystems to beimplemented easily without having to consider the synchronizationissues.</para><para>The infrastructure maintains a mutex for each entry in each ofthe main tables: filesystem table, mount table and file table. Foreach class of operation each of these mutexes may be locked before thecorresponding filesystem operation is invoked.</para><para>The synchronization protocol required by a filesystem is describedby the <structfield>syncmode</structfield> field of the filesystemtable entry. This is a combination of the following flags:</para><variablelist><varlistentry><term><literal>CYG_SYNCMODE_FILE_FILESYSTEM</literal></term><listitem><para>Lock the filesystem table entry mutexduring all filesystem level operations.</para></listitem></varlistentry><varlistentry><term><literal>CYG_SYNCMODE_FILE_MOUNTPOINT</literal></term><listitem><para>Lock the mount table entry mutexduring all filesystem level operations.</para></listitem></varlistentry><varlistentry><term><literal>CYG_SYNCMODE_IO_FILE</literal></term><listitem><para>Lock the file table entry mutex during allI/O operations.</para></listitem></varlistentry><varlistentry><term><literal>CYG_SYNCMODE_IO_FILESYSTEM</literal></term><listitem><para>Lock the filesystem table entry mutex during all I/O operations.</para></listitem></varlistentry><varlistentry><term><literal>CYG_SYNCMODE_IO_MOUNTPOINT</literal></term><listitem><para>Lock the mount table entry mutex during all I/O operations.</para></listitem></varlistentry><varlistentry><term><literal>CYG_SYNCMODE_SOCK_FILE</literal></term><listitem><para>Lock the file table entry mutex during all socket operations.</para></listitem></varlistentry><varlistentry><term><literal>CYG_SYNCMODE_SOCK_NETSTACK</literal></term><listitem><para>Lock the network stack table entry mutex during all socket operations.</para></listitem></varlistentry><varlistentry><term><literal>CYG_SYNCMODE_NONE</literal></term><listitem><para>Perform no locking at all during any operations.</para></listitem></varlistentry></variablelist><para>The value of the <structfield>syncmode</structfield> field in thefilesystem table entry will be copied by the infrastructure to theopen file object after a successful <function>open()</function> operation.</para></chapter><!-- }}} --><!-- {{{ Initialization and Mounting --><chapter id="fileio-mounting"><title>Initialization and Mounting</title><para>As mentioned previously, mount table entries can be sourced from twoplaces. Static entries may be defined by using the<literal>MTAB_ENTRY()</literal> macro. Such entries will beautomatically mounted on system startup.  For each entry in the mounttable that has a non-null <structfield>name</structfield> field thefilesystem table is searched for a match with the<structfield>fsname</structfield> field. If a match is found thefilesystem's <structfield>mount</structfield> entry is called and ifsuccessful the mount table entry marked valid and the<structfield>fs</structfield> field initialized. The<function>mount()</function> function is responsible for initializingthe <structfield>root</structfield> field.</para><para>The size of the mount table is defined by the configuration value<literal>CYGNUM_FILEIO_MTAB_MAX</literal>. Any entries that have notbeen statically defined are available for use by dynamic mounts.</para><para>A filesystem may be mounted dynamically by calling <function>mount()</function>. Thisfunction has the following prototype:</para><programlisting width=72>int mount( const char *devname,           const char *dir,	   const char *fsname);</programlisting><para>The <parameter>devname</parameter> argument identifies a device thatwill be used by this filesystem and will be assigned to the<structfield>devname</structfield> field of the mount table entry.</para><para>The <parameter>dir</parameter> argument is the mount point name, itwill be assigned to the <structfield>name</structfield> field of themount table entry.</para><para>The <parameter>fsname</parameter> argument is the name of theimplementing filesystem, it will be assigned to the<structfield>fsname</structfield> entry of the mount table entry.</para><para>The process of mounting a filesystem dynamically is as follows. Firsta search is made of the mount table for an entry with a NULL<structfield>name</structfield> field to be used for the new mountpoint. The filesystem table is then searched for an entry whose namematches <structfield>fsname</structfield>. If this is successful thenthe mount table entry is initialized and the filesystem's<function>mount()</function> operation called. If this is successful,the mount table entry is marked valid and the<structfield>fs</structfield> field initialized.</para><para>Unmounting a filesystem is done by the <function>umount()</function>function. This can unmount filesystems whether they were mountedstatically or dynamically.</para><para>The <function>umount()</function> function has the following prototype:</para><programlisting width=72>int umount( const char *name );</programlisting><para>The mount table is searched for a match between the<parameter>name</parameter> argument and the entry<structfield>name</structfield> field. When a match is found thefilesystem's <function>umount()</function> operation is called and ifsuccessful, the mount table entry is invalidated by setting its<structfield>valid</structfield> field false and the<structfield>name</structfield> field to NULL.</para><!-- --></chapter><!-- }}} --><!-- {{{ Sockets --><chapter id="fileio-sockets"><title>Sockets</title><para>If a network stack is present, then the FILEIO infrastructure alsoprovides access to the standard BSD socket calls.</para><para>The netstack table contains entries which describe the networkprotocol stacks that are in the system image. Each resident stackshould export an entry to this table using the<literal>NSTAB_ENTRY()</literal> macro.</para><para>Each table entry has the following structure:</para><programlisting width=72>struct cyg_nstab_entry{    cyg_bool            valid;          // true if stack initialized    cyg_uint32          syncmode;       // synchronization protocol    char                *name;          // stack name    char                *devname;       // hardware device name    CYG_ADDRWORD        data;           // private data value    int     (*init)( cyg_nstab_entry *nste );    int     (*socket)( cyg_nstab_entry *nste, int domain, int type,		       int protocol, cyg_file *file );};</programlisting>

⌨️ 快捷键说明

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