QNX6 文件系统¶
qnx6fs 被较新的 QNX 操作系统版本使用(例如 Neutrino)。它在 QNX 6.4.0 中引入,并自 6.4.1 起默认使用。
选项¶
mmi_fs:挂载文件系统,例如 Audi MMI 3G 系统所使用的文件系统
规范¶
qnx6fs 与传统的 Unix 文件系统有许多相似之处。它具有块、inode 和目录的概念。
在 QNX 上,可以创建小端和大端 qnx6 文件系统。此功能使得可以为目标(QNX 用于各种嵌入式系统)平台创建和使用不同字节顺序的文件系统,该平台运行在不同的字节顺序上。
Linux 驱动程序透明地处理字节顺序(LE 和 BE)。
块¶
设备或文件中的空间被划分为块。这些块的大小是固定的,为 512、1024、2048 或 4096 字节,在创建文件系统时决定。
块指针为 32 位,因此可寻址的最大空间为 2^32 * 4096 字节或 16TB。
超级块¶
超级块包含有关文件系统的所有全局信息。每个 qnx6fs 都有两个超级块,每个超级块都有一个 64 位序列号。该序列号用于标识“活动”超级块。在写入模式下,每次新的快照(每次同步写入后),新主超级块的序列号都会增加(旧超级块序列号 + 1)。
因此,基本上,快照功能是通过原子最终更新序列号来实现的。在更新该序列号之前,所有修改都是通过复制该特定写入请求(或期间)期间所有修改的块,并在非活动的超级块下构建新的(稳定的)文件系统结构来完成的。
每个超级块都保存一组用于不同文件系统部分的根 inode。(Inode、位图和长文件名)这些根节点中的每一个都保存着存储数据总大小和该特定树中的寻址级别等信息。如果级别值为 0,则每个节点最多可以寻址 16 个直接块。
级别 1 添加一个额外的间接寻址级别,其中每个间接寻址块最多可保存块大小 / 4 字节的指向数据块的指针。级别 2 添加一个额外的间接寻址块级别(因此,已经可以通过这样的树寻址多达 16 * 256 * 256 = 1048576 个块)。
未使用的块指针始终设置为 ~0 - 无论根节点、间接寻址块还是 inode。
数据叶始终位于最低级别。因此,没有数据存储在较高的树级别上。
第一个超级块位于 0x2000。(0x2000 是引导块大小) Audi MMI 3G 的第一个超级块直接从字节 0 开始。
第二个超级块的位置可以从超级块信息(文件系统块的总数)计算得出,或者取最高的设备地址,将最后 3 个字节归零,然后从该地址减去 0x1000。
0x1000 是为每个超级块保留的大小 - 与文件系统的块大小无关。
Inode¶
文件系统中的每个对象都由一个 inode 表示(索引节点)。inode 结构包含指向文件系统块的指针,这些文件系统块包含对象中保存的数据以及有关对象的所有元数据,但其长名称除外(文件名超过 27 个字符)。有关对象的元数据包括权限、所有者、组、标志、大小、使用的块数、访问时间、更改时间和修改时间。
对象模式字段是 POSIX 格式。(这使得事情更容易)
如果可以使用 16 个直接块寻址对象数据,则还有指向前 16 个块的指针。
对于超过 16 个块,使用另一种树形式的间接寻址。(方案与超级块根节点使用的方案相同)
文件大小存储为 64 位。Inode 计数从 1 开始。(而长文件名 inode 从 0 开始)
目录¶
目录是一个文件系统对象,就像文件一样具有 inode。它是一个特殊格式的文件,包含将每个名称与 inode 号关联的记录。
“.” inode 号指向目录 inode
“..” inode 号指向父目录 inode
每个文件名记录还包含一个文件名长度字段。
一个特殊情况是长文件名或子目录名称。
这些在相应的目录记录中设置了 0xff 的文件名长度字段,以及存储在该记录中的长文件名 inode 号。
使用该长文件名 inode 号,可以从超级块长文件名根节点指针开始遍历长文件名树。
特殊文件¶
符号链接也是具有 inode 的文件系统对象。它们在 inode 模式字段中有一个特定位,将其标识为符号链接。
目录项文件 inode 指针指向目标文件 inode。
硬链接具有 inode、目录项,但设置了特定的模式位,没有块指针,并且指向目标文件 inode 的目录文件记录。
字符和块特殊设备在 QNX 中不存在,因为这些文件由 QNX 内核/驱动程序处理,并在 /dev 中创建,与底层文件系统无关。
长文件名¶
长文件名存储在单独的寻址树中。起点是活动超级块中的长文件名根节点。
每个数据块(树叶)保存一个长文件名。该文件名限制为 510 字节。前两个起始字节用作实际文件名的长度字段。
如果该结构应适用于所有允许的块大小,则很明显,为什么存储的实际文件名限制为 510 字节。
位图¶
qnx6fs 文件系统分配位图存储在超级块中位图根节点下的树中,位图中的每一位代表一个文件系统块。
第一个块是块 0,它在超级块开始后 0x1000 开始。因此,对于正常的 qnx6fs,0x3000(引导块 + 超级块)是块 0 所在的物理地址。
如果设备小于位图中的寻址空间,则将最后一个位图块末尾的位设置为 1。
位图系统区域¶
位图本身分为三个部分。
首先是系统区域,它分为两个半部分。
然后是用户空间。
静态的、固定预分配系统区域的要求来自 qnx6fs 处理写入的方式。
每个超级块都有自己的系统区域的一半。因此,超级块 #1 始终使用下半部分的块,而超级块 #2 仅写入由上半部分位图系统区域位表示的块。
位图块、inode 块和这两个树结构的间接寻址块被视为系统块。
其背后的原理是,一个写入请求可以在新的快照上工作(非活动的 - 或序列号较低的超级块的系统区域),同时在系统区域的另一半中仍然有一个完整的稳定文件系统结构。
当完成写入(完成同步写入、达到最大同步跃迁时间或请求文件系统同步)时,先前非活动的超级块的序列号原子增加,并且文件系统切换到该 - 然后声明为稳定的 - 超级块。
对于系统区域之外的所有数据,块只是在写入时复制。