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 添加了一个额外的间接寻址级别,其中每个间接寻址块最多包含 blocksize / 4 字节的指向数据块的指针。 级别 2 添加了一个额外的间接寻址块级别(因此,已经可以寻址 16 * 256 * 256 = 1048576 个块)。

无论根节点、间接寻址块还是 inode,未使用的块指针始终设置为 ~0。

数据叶始终位于最低级别。 因此,没有数据存储在较高的树级别上。

第一个超级块位于 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 的文件名长度字段,以及也存储在该记录中的 longfile inode 编号。

使用该长文件名 inode 编号,可以从超级块长文件名根节点指针开始遍历长文件名树。

特殊文件

符号链接也是具有 inode 的文件系统对象。 它们在 inode 模式字段中有一个特定的位来标识它们作为符号链接。

目录条目文件 inode 指针指向目标文件 inode。

硬链接有一个 inode,一个目录条目,但是设置了一个特定的模式位,没有块指针,并且目录文件记录指向目标文件 inode。

字符和块特殊设备在 QNX 中不存在,因为这些文件由 QNX 内核/驱动程序处理,并在 /dev 中创建,独立于底层文件系统。

长文件名

长文件名存储在一个单独的寻址树中。 起始点是活动超级块中的长文件名根节点。

每个数据块(树叶)保存一个长文件名。 该文件名限制为 510 个字节。 前两个起始字节用作实际文件名的长度字段。

如果该结构要适用于所有允许的块大小,那么很明显,为什么存储的实际文件名限制为 510 个字节。

位图

qnx6fs 文件系统分配位图存储在超级块中位图根节点下的树中,并且位图中的每个位代表一个文件系统块。

第一个块是块 0,它在超级块开始后 0x1000 开始。 因此,对于正常的 qnx6fs,0x3000(引导块 + 超级块)是块 0 所在的物理地址。

如果设备小于位图中的寻址空间,则最后一个位图块末尾的位设置为 1。

位图系统区域

位图本身分为三个部分。

首先是系统区域,它分为两个部分。

然后是用户空间。

对静态、预先分配的固定系统区域的要求来自 qnx6fs 如何处理写入。

每个超级块都有自己的系统区域的一半。 因此,超级块 #1 始终使用下半部分的块,而超级块 #2 仅写入由上半部分位图系统区域位表示的块。

位图块、Inode 块和这两个树结构的间接寻址块被视为系统块。

这背后的原理是,写入请求可以在新的快照上工作(非活动的 - 或较低序列号的超级块的系统区域),同时在系统区域的另一半中仍然存在完整的稳定文件系统结构。

完成写入后(同步写入完成、达到最大同步跃迁时间或请求文件系统同步),先前非活动的超级块的序列原子性地增加,并且 fs 切换到该 - 然后声明为稳定 - 超级块。

对于系统区域之外的所有数据,块只是在写入时被复制。