RTEMS文件系统(6):内存文件系统(上)

%6 In-Memory Filesystem
本节描述了内存文件系统~(In-Memory Filesystem,IMFS)。IMFS~是一个功能齐全的在内存中保存所有信息的~POSIX~文件系统。

%6.1 IMFS Per Node Data Structure

每一个普通文件、设备、硬链接和目录都由一个叫~jnode~的数据结构表示。
jnode~由以下的结构体类型定义:


    struct IMFS_jnode_tt {
        Chain_Node Node; /* for chaining them together */
        IMFS_jnode_t *Parent; /* Parent node */
        char name[NAME_MAX+1]; /* "basename" */
        mode_t st_mode; /* File mode */
        nlink_t st_nlink; /* Link count */
        ino_t st_ino; /* inode */
        uid_t st_uid; /* User ID of owner */
        gid_t st_gid; /* Group ID of owner */
        time_t st_atime; /* Time of last access */
        time_t st_mtime; /* Time of last modification */
        time_t st_ctime; /* Time of last status change */
        IMFS_jnode_types_t type; /* Type of this entry */
        IMFS_typs_union info;
    };



此结构中的字段列举如下,并附在文件系统中所起作用的简短说明。


 Node:该字段是为了让整个~jnode~结构组成一个链表;

 Parent:该字段是指向另外一个~jnode~结构的指针,该节点是该字段出现节点的合乎逻辑的父节点;
该字段可以是~NULL,如果删除与此节点关联的文件,但有这个文件打开的文件描述符或仍有这个节点的硬链接;

 name:在文件系统层次结构树中该节点的名称。例如:
如果一个~jnode~完整路径名是~"a/b/c",jnode~的该字段将包含以~NULL~结尾的字符串~"c"。

 st_mode:文件或目录的标准~Unix~访问权限;

 st_nlink:这个文件的硬链接数。当第一次创建~jnode,它的链接计数设置为~1。除非它的链接数是小于~1,jnode~及其相关资源不能被删除;

 st_ino:该字段是全局唯一的节点标识号;

 st_uid:该字段是该文件所有者的用户~ID;

 st_gid:该字段是该文件所有者的组~ID;

 st_atime:该字段表示最后访问这个文件的时间;

 st_mtime:该字段表示最后修改这个文件的时间;

 st_ctime:该字段表示这个文件最后状态改变的时间;

 type:该字段表示节点的类型,必须是以下类型之一:

[a.] IMFS_DIRECTORY
[b.] IMFS_MEMORY_FILE
[c.] IMFS_HARD_LINK
[e.] IMFS_SYM_LINK
[f.] IMFS_DEVICE


 info:该字段包含一个与文件类型相关的联合体~(见~imfs.h~中的~IMFS_type_union)。

[a.] IMFS_DIRECTORY:
IMFS~目录包含了一个动态的记录所有从属于该目录节点的文件和目录的链表结构;

[b.] IMFS_MEMORY_FILE:
在内存文件系统中常规文件存储数据。为文件动态分配~128~字节的内存块用于存储数据。
一个指针阵列记录着每个内存块分配的地址用于追踪每个内存块。
单,双和三重指针用来记录文件所有部分的位置。
一个~IMFS~文件的内存组织将在本节的其他地方讨论;

[c.] IMFS_HARD_LINK:
IMFS~文件系统支持硬链接的概念对于其他在~IMFS~文件系统上的节点。
这些硬链接是指向在同一个文件系统中其他节点的指针。
这种类型的链接不能跨越文件系统边界;


[d.] IMFS_SYM_LINK:
IMFS~文件系统支持符号链接的概念对于其他任何文件系统上的节点。
一个符号链接是由一个指向表示目标节点路径的字符串指针构成的。
这种类型的链接可以跨文件系统边界。
正如大多数~UNIX~版本支持的符号链接,一个符号链接可以指向一个不存在的文件;

[e.] IMFS_DEVICE:
所有~RTEMS~设备现以文件的形式出现在内存文件文件系统中。
在系统初始化时,所有设备都登记为该文件系统的节点。




%6.2 Miscellaneous IMFS Information
%6.3 Memory associated with the IMFS
一个基于内存的文件系统从系统的内存资源资源中生成文件和目录。
当卸载文件系统的时候,支持该文件系统的内存资源被释放。
为了释放这些资源,将执行对树状结构的文件系统的遍历操作。
遇到文件系统的叶节点,则释放其占用的资源。在处理过程中遇到空目录,释放空目录占用的资源。

%6.3.1 Node removal constraints for the IMFS
IMFS~遵守一般文件系统的节点删除要求。见 Section 5.2
[File and Directory Removal Constraints], Page 27。

%6.3.2 IMFS General Housekeeping Notes
以下是~IMFS~较为隐蔽的内部管理注意事项列表:

 如果全局变量~rtems_filesystem_current~引用我们正在试图移除的节点,
这个结构的~node_access~字段必须设置为~NULL,使其变为无效;

 如果节点是~IMFS_MEMORY_FILE~类型,在释放节点占用内存之前先释放文件占用的内存。
使用~IMFS_memfile_remove()~函数。


%6.4 IMFS Operation Tables
%6.4.1 IMFS Filesystem Handler Table Functions
rtems_filesystem_operation_table~结构类型定义了~OPS~表函数。
它定义了一个给定文件系统上与具体节点类型相关的函数。
RTEMS~配置表支持的每一个文件系统都有一个~OPS~表与之对应。
该结构定义如下,在后续的小节中将详细介绍这个表中的每一个函数的开发信息。


    rtems_filesystem_operations_table IMFS_ops = {
        IMFS_eval_path,
        IMFS_evaluate_for_make,
        IMFS_link,
        IMFS_unlink,
        IMFS_node_type,
        IMFS_mknod,
        IMFS_rmnod,
        IMFS_chown,
        IMFS_freenodinfo,
        IMFS_mount,
        IMFS_initialize,
        IMFS_unmount,
        IMFS_fsunmount,
        IMFS_utime,
        IMFS_evaluate_link,
        IMFS_symlink,
        IMFS_readlink
    };


%6.4.1.1 IMFS evalpath()
%Corresponding Structure Element:
%XXX
%Arguments:
%XXX
%File:
%XXX
%Description:
%XXX

%6.4.1.2 IMFS evalformake()
%Corresponding Structure Element:
%XXX
%Arguments:
%XXX
%File:
%XXX
%Description:
%XXX


%6.4.1.3 IMFS_link()
IMFS_link()~函数与结构体对应的字段是~link;参数:


    rtems_filesystem_location_info_t *to_loc, /* IN */
    rtems_filesystem_location_info_t *parent_loc, /* IN */
    const char *token  /* IN */


文件:imfs_link.c。

描述:
这个函数是在~IMFS~文件系统里创建一个硬链接。
它首先检查我们正试图创建硬链接的节点的~st_nlink~计数(链接计数)。如果链接计数超过~LINK_MAX~将返回一个错误。
该链接的名称将被归一化(normalized),删除这个名字结尾的多余的分隔符。
IMFS_create_node~将创建一个具有以下特点的文件系统节点:


 用~link.c~文件中的~link()~函数确定父节点;
 类型将被设置为~IMFS_HARD_LINK;
 名称将被设置为归一化的名称;
 硬链接的模式将被设置成目标节点的模式。


如果分配一个新节点时发生问题将返回一个错误。
目标节点的~st_nlink~计数将递增反映新的链接。
链接文件的时间字段将被设置成硬链接的创建时间。

%6.4.1.4 IMFS unlink()
%Corresponding Structure Element:
%XXX
%Arguments:
%XXX
%File:
%XXX
%Description:
%XXX

%6.4.1.5 IMFS_node_type()
IMFS_node_type()~函数与结构中的字段~node_type()~相对应;
参数:

    rtems_filesystem_location_info_t *pathloc /* IN */


文件:imfs_ntype.c。

描述:此函数将为文件系统中选定节点定位保存所有权信息的~IMFS_jnode_t~结构。
这个结构指向~pathloc->node_access~的位置。
IMFS_jnode_t~类型字段表示节点的类型,是下面列出的节点类型之一:

 RTEMS_FILESYSTEM_DIRECTORY
 RTEMS_FILESYSTEM_DEVICE
 RTEMS_FILESYSTEM_HARD_LINK
 RTEMS_FILESYSTEM_MEMORY_FILE


%6.4.1.6 IMFS_mknod()
IMFS_mknod()~函数与结构体中的字段~mknod~相对应;参数:

    const char *token, /* IN */
    mode_t      mode, /* IN */
    dev_t       dev, /* IN */
    rtems_filesystem_location_info_t *pathloc /* IN & OUT */


文件:imfs_mknod.c。

描述:此函数将检查模式参数,以确定我们要创建的是一个目录,普通文件或设备节点。
其他节点类型是不允许创建的并会导致断言失败。
函数将为~jnode~分配内存空间,并且将根据指定的节点类型设置节点。
IMFS_create_node()~函数执行节点的分配和设置。
唯一可能发生的问题是当我们试图为~jnode~申请内存空间时,报告当前的内存不足~(ENOMEN)。

%6.4.1.7 IMFS_rmnod()
%Corresponding Structure Element:
%XXX
%Arguments:
%XXX
%File:
%XXX
%Description:
%XXX


%6.4.1.8 IMFS_chown()
IMFS_chown()~函数与结构体的字段~chown~相对应;参数:

    rtems_filesystem_location_info_t *pathloc /* IN */
    uid_t owner /* IN */
    gid_t group /* IN */


文件:imfs_chown.c。

描述:此函数将为文件系统中选定节点定位保存所有权信息的~IMFS_jnode_t~结构。
这个结构指向~pathloc->node_access~的位置。
然后修改节点的~st_uid~和~st_gid~字段。由于这是一个基于内存文件系统,
不需要采取其他措施即可改变~IMFS_jnode_t~结构的所有权。


%6.4.1.9 IMFS_freenod()

IMFS_freenod()~函数与结构中的字段~freenod~相对应;参数:

    rtems_filesystem_location_info_t *pathloc /* IN */


文件:imfs_free.c。

描述:这个函数是~IMFS~的私有函数。
IMFS~函数需要释放已被申请的节点时调用该函数。
例如,unlink~和~rmnod~函数中可能会调用该函数。

注意:此例程不应该与文件系统回调~freenod~函数相混淆。
IMFS~申请内存直到节点不再存在。

%6.4.1.10 IMFS_freenodinfo()
IMFS_freenodinfo()~函数与结构体中的字段~freenodinfo~相对应;参数:


    rtems_filesystem_location_info_t *pathloc /* IN */


文件:imfs_free.c。

描述:内存文件系统~(IMFS)~在评估函数中不需要申请内存。应此,此函数秩序简单的返回~0~即可。

%6.4.1.11 IMFS_mount()
IMFS_mount()~函数与结构体中的字段~mount~相对应。参数:

    rtems_filesystem_mount_table_entry_t *mt_entry

文件:imfs_mount.c。

描述:这个函数向文件系统提供了一个特殊的操作,可使包含挂载点的系统挂载一个文件系统。
它将确定我们正在试图挂载的挂载点是一个~IMFS_DIRECTORY~类型的节点。

节点的信息字段将被改变,使得~info.directory.mt_fs~字段指向挂载在这个挂载点上的文件系统相关的挂载表项。
检查~info.directory.mt_fs~字段以确定是否有一个文件系统挂载在该目录上。
如果为~NULL,该目录不能作为挂载点。
否则表明该目录可以作为挂载点,并且~info.directory.mt_fs~的值可以用来定位与在这个目录下挂载的文件系统相关的挂载链表项目。

%6.4.1.12 IMFS_fsmount_me()
IMFS_fsmount_me()~函数与结构体中的字段~fsmount_me~相对应;参数:

    rtems_filesystem_mount_table_entry_t *mt_entry

文件:imfs_init.c。

描述:
此函数是由文件系统提供,用于在~RTEMS~环境下挂载文件系统时处理这个文件系统内部管理细节。
%This function is provided with a filesystem to take care of the internal filesystem management details associated with
%mounting that filesystem under the RTEMS environment.
该函数不负责包含挂载点的文件系统的挂载细节。

rtems_filesystem_mount_table_entry_t~结构包含的关键字段如下:

    rtems_filesystem_location_info_t *mt_point_node,


此结构包含与挂载点相关的信息。
这允许我们可找到与含有挂载点的文件系统相关的~OPS~表和处理函数。


    rtems_filesystem_location_info_t *fs_root_node,

此结构包含与被挂载文件系统根节点相关的信息。
这允许我们可找到与被挂载文件系统相关的~OPS~表和处理函数。


    rtems_filesystem_options_t options,

控制访问方式,只读或读/写访问。


    void *fs_info,


它是一个已分配内存块的指针,用于保存任何文件系统的具有全局属性的特定信息。
这个分配区域非常重要,因为它可以让我们不止一次在~RTEMS~系统下挂载相同的文件系统类型。
每个挂载文件系统的实例有其自己的一套全局性的管理信息,与其他被挂载文件系统类型实例的全局管理信息是分开的。


    rtems_filesystem_limits_and_options_t pathconf_info,


该表包含了下列与已挂载文件系统相关的值:


 link_max
 max_canon
 max_input
 name_max
 path_max
 pipe_buf
 posix_async_io
 posix_chown_restrictions
 posix_no_trunc
 posix_prio_io
 posix_sync_io
 posix_vdisable


这些值可以通过~pathconf()~和~fpathconf()~函数访问。


    const char *dev


为了包含一个字符串,用于标识包含文件系统信息的设备。
在当前实现的文件系统是基于内存的,并不需要设备的详细信息。

如果~mt_point_node.node_access~为~NULL,那么我们安装基本文件系统。
该函数将创建一个~IMFS~文件系统的根目录节点。
该节点对于所有者、组和其他组将有读、写和执行权限。
该节点名称将是一个空字符串。
为~IMFS~文件系统分配并初始化一个文件系统的信息结构~(fs_info)。
在挂载表项中的~fs_info~指针将被设置为指向文件系统的信息结构。

挂载表中的~pathconf_info~字段将被设置成相应的配置常数路径~(IMFS_LIMITS_AND_OPTIONS)~的表(???)。

fs_root_node~结构按照以下步骤进行填充:

 指针指向文件系统分配的根节点;
 填充~IMFS~文件系统的目录节点处理程序;
 填充~IMFS~的~OPS~表函数。


如果成功,返回~0~给调用该函数的任务,否则返回~1。


%6.4.1.13 IMFS_unmount()
IMFS_unmount()~函数与结构中的字段~unmount~想对应。参数:

    rtems_filesystem_mount_table_entry_t *mt_entry

文件:imfs_unmount.c。

描述:这个例程允许~IMFS~卸载一个已挂载到~IMFS~目录上的文件系统。
作为一个挂载目录,需验证挂载项目、挂载点和节点访问。
mt_fs~被设置成~NULL。
这是向~IMFS~表明该目录节点不在是一个挂载点。
此外,它将允许因挂载文件系统而被隐藏的目录重新可见。

%6.4.1.14 IMFS_fsunmount()
IMFS_fsunmount()~函数与结构体中的字段~fsunmount~相对应;
参数:

    rtems_filesystem_mount_table_entry_t *mt_entry

文件:imfs_init.c。

描述:这个函数卸载这个~IMFS~文件系统的实例。
它是与~IMFS_initialize~函数相对的函数。
在~fsunmount_me~中的通用代码将调用该函数。
所有的方法都是循环找到第一个没有孩子的节点并从树上删除节点,从而释放分配的资源。
如此这样做,直到所有分配的节点都被释放。

%6.4.1.15 IMFS utime()
%Corresponding Structure Element:
%XXX
%Arguments:
%XXX
%File:
%XXX
%Description:
%XXX

%6.4.1.16 IMFS eval link()
%Corresponding Structure Element:
%XXX
%Arguments:
%XXX
%File:
%XXX
%Description:
%XXX

你可能感兴趣的:(File,null,table,Access,constraints,structure)