5 Filesystem Implementation Requirements
本章详细描述所有文件系统的实现都必须坚持的要求。
5.1 General
RTEMS~文件系统框架的用意是与~POSIX~文件和目录接口标准相兼容。
下面文件系统的特性导致了功能交换层。
向应用程序提供与~POSIX~标准兼容的函数集,使他们能够与文件系统中的文件,设备和目录对接。
- 对这些函数来说接口不会影响下级文件系统的实现(???);
- 在~RTEMS~文件系统框架下开发允许挂载不同类型的文件系统到基础文件系统上;
- 定位文件信息的机制可能在不同文件类型之间有很大的差异;
- 定位一个文件的过程可能需要跨越文件系统边界;
- 文件系统之间的转换和在不同的文件系统下处理需要访问的信息在~POSIX~函数级别是不可见的;
- POSIX~接口标准中的一些函数通过用文件字符串名称的方式提供对文件的访问,另外一些通过整数文件描述符进行访问;
- 整数文件描述符的本质及其相关的处理与操作系统和文件系统高度相关;
- 目录和设备信息必须被一些相同的可用于文件的函数加以处理;
- 目录的形式内容和设备的信息与普通文件是有很大的不同的;
- 文件,目录和设备代表了树结构中的元素(节点);
- 用于处理文件系统上每个节点类型的规则是与节点相关的,但不在~POSIX~接口的函数中考虑。
5.2 文件和目录删除约束
所有的文件系统都必须兑现以下~POSIX~的约束。
- 如果一个节点是一个带有孩子的目录,它不能被删除;
- 任何文件系统的根结点,无论是基础文件系统或挂载文件系统的,都不能被删除;
- 一个节点作为文件系统挂载点的目录是不能被删除的;
- 支持硬链接的文件系统,需要维护连结数。在移动节点之前,节点接数要减一。链接数必须小于一以允许节点的删除。
5.3 API Layering
5.3.1 Mapping of Generic System Calls to Filesystem Specific Functions
通用的系统调用清单包括~open()、read()、write()、close()~等函数。
POSIX Application Programs Interface~的文件和目录一节列出了一系列函数及其用于获取访问文件系统信息的调用参数。
对于应用程序,这些函数允许访问任何已挂载文件系统的信息,不需要相关文件系统类型的显性知识或文件系统的挂载配置。
以下是向应用程序提供的函数:
- access()
- chdir()
- chmod()
- chown()
- close()
- closedir()
- fchmod()
- fcntl()
- fdatasync()
- fpathconf()
- fstat()
- fsync()
- ftruncate()
- link()
- lseek()
- mkdir()
- mknod()
- mount()
- open()
- opendir()
- pathconf()
- read()
- readdir()
- rewinddir()
- rmdir()
- rmnod()
- scandir()
- seekdir()
- stat()
- telldir()
- umask()
- unlink()
- unmount()
- utime()
- write()
文件系统的类型以及文件系统内的节点类型
决定了处理的性质,必须为上述对象执行上面函数进行处理。
RTEMS~文件系统提供了一个框架,允许开发和集成新的文件系统,不需要改变基本的框架。
为了提供所需要的功能切换,每个~POSIX~文件和目录函数实现成一个~shell~函数(???)。
Shell~函数遵守~POSIX~接口标准。
在这个功能外壳里(????),访问文件系统和节点类型信息是通过调用合适的文件系统和节点类型中特殊的处理函数处理~POSIX~函数调用。
5.3.2 File/Device/Directory function access via file control block rtems_libio_t structure
POSIX~open()~函数返回一个整数文件描述符作为文件控制块信息以引用的特定文件。
文件控制块包含的信息用于定位节点、文件系统、安装表和处理程序信息。
- 文件描述符表:
这是一个~RTEMS~内部数据结构,跟踪所有当前定义的文件系统中的描述符。
该文件的~open()~操作返回的索引在这个表中引用一个位置。
该位置包含指向此文件的文件描述符表项的指针。rtems_libio_t~结构代表文件控制块;
- 文件描述符表中的项目申请:
访问文件描述符表是由信号量控制,申请通过~rtems_libio_allocate()~函数实现。
此函数将获取一个信号量然后扫描文件控制块来确定哪些是可供使用的空位置。
第一空位置将被标记为使用,而这个位置的索引作为~open()~返回的文件描述符被返回。
完成对文件控制块表改变后,信号量被释放,以允许对这个表的其他操作;
- 文件描述符表最大条目数的通过~src/exec/sapi/headers/confdefs.h~文件进行配置。
如果定义了~CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS~常数,它的值将代表文件描述符的最大允许的数量。
如果~CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS~没有指定,它的默认值为~20,将作为文件描述符的数量上限。
- 文件控制块,rtems_libio_t~结构:
struct rtems_libio_tt {
rtems_driver_name_t *driver;
off_t size;
off_t offset;
unsigned32 flags;
rtems_filesystem_location_info_t pathinfo;
Objects_Id sem;
unsigned32 data0;
void data1;
void file_info;
rtems_filesystem_file_handlers_r handlers;
};
- 一个文件控制块可以为普通文件,设备和目录而存在。以下字段对文件和目录的访问是非常重要的:
- size:对于一个文件,代表目前在一个文件中存储的字节数。对于目录这个字段是不填写的;
- offset:对于一个文件,这是文件位置相对于该文件开始位置的字节数。对于目录,这是~dirent~结构序列的字节偏移量;
- pathinfo: 这是一个结构,提供指向节点的信息指针、指向~OPS~表函数的指针、指向处理函数的指针和指向与此节点关联的~mount~表项的指针;
- file_info:一个指向节点处理函数信息的指针;
- handlers:指向一个处理函数表,用于通过一个文件描述符索引操作一个文件、设备或目录。
5.3.3 File/Directory function access via rtems filesystem location info t structure
下面的~rtems_filesystem_location_info_tt~结构提供了足够的信息来处理一个挂载文件系统上的节点。
struct rtems_filesystem_location_info_tt {
void *node_access;
rtems_filesystem_file_handlers_r *handlers;
rtems_filesystem_operations_table *ops;
rtems_filesystem_mount_table_entry_t *mt_entry;
};
它包含一个指向文件系统特定的节点结构的无类型指针,一个指向包含该节点的文件系统的~OPS~表的指针
一个指向该节点的处理程序表指针和一个指向与该节点所在文件系统相关的~mount~表项。