下列例子进一步分析了盘区描述符和 xad 结构的用法: 连续分配的 1041377 字节文件。 相同的 1041377 字节文件,但在磁盘上拆分成三段。 1041377 字节的文件,但里面有一个"洞"(稀疏文件)。 连续分配的 16GB 文件。 在所有这些例子中,聚集块尺寸都是 1KB。 连续分配的 1041377 字节尺寸文件: 该文件需要 1017 个 1KB 聚集块,(在最后一个聚集块中,有 31 个字节丢失成为内部存储碎片)。要描述这个连续文件只需要一个 xad 结构: flag 这里不讨论 offset 0 /* the beginning of the file */ length 1017 /* 1017 1KB aggregate blocks */ address xxxxx /* aggregate block # */ 相同的 xad 结构能够表示任何长度为 1040385 (1016 * 1024 + 1)到 1041408 (1017 * 1024)的连续文件,因为盘区描述符只表示小于聚集块大小粒度的尺寸。只有 inode 的 di_size 字段记录字节粒度。 在 1041377 字节文件分三段: 假设相同的文件拆分成磁盘上三个不同盘区:一个为 495 个聚集块长,一个为 22,一个为 500。需要三个 xad 结构来表示该文件,每个物理盘区需要一个: xad #0 : flag 这里不讨论 offset 0 /* the beginning of the file */ length 495 /* 495 1KB aggregate blocks */ address xxxxx /* aggregate block # */ xad #1: flag 这里不讨论 offset 495 /* the beginning of the file */ length 22 /* 22 1KB aggregate blocks */ address yyyyy /* aggregate block # */ xad #2: flag 这里不讨论 offset 517 /* the beginning of the file */ length 500 /* 500 1KB aggregate blocks */ address zzzzz /* aggregate block # */ 该例中,0 号 xad 描述文件开始的 495 个物理聚集块。 xad_offset 字段包含 0,因为该 xad 描述以逻辑偏移量 0 开始的字节。第二个 xad,1 号 xad,描述文件接下来的 22 个物理聚集块。 xad_offset 字段包含 495,因为该 xad 描述以逻辑偏移量 506880 (495 * 1024) 开始的字节;前面的字节由 xad 0 描述。最后一个 xad 描述文件的最后 500 块。这里, xad_offset 字段是 517。请注意,对于非稀疏文件,给定 xad 的 xad_offset 字段等于所有以前 xad 结构长度和(在本例中,517 = 495 + 22)。如果这一关系总是成立的,那么 xad_offset 字段就是冗余的,可以消除。然而,下一个例子显示,对于稀疏文件, xad_offset 字段不是冗余的。 1041377 字节的稀疏文件: 考虑经由以下 POSIX 风格的操作而创建的文件: fd = create ("newfile", blah blah blah); write (fd, "hi", 2); lseek (fd, 1041374, 0); write (fd, " bye" , 3); 该文件有以逻辑字节偏移量 0 开始的两字节数据("hi"),还有以逻辑字节偏移量 1,041,374 开始的三字节数据 ("bye"),并且在这两者之间全为 0(稀疏的)。文件的长度为 1041377 字节。 通常,JFS 不分配物理磁盘空间以保存从不写入文件的字节范围。因此,将占用两个 xad 结构来表示该文件:一个为包含 "hi" 数据的盘区,一个为包含 "bye" 数据的盘区: xad #0 : flag 这里不讨论 offset 0 /* the beginning of the file */ length 1 /* 1 1KB aggregate blocks */ address xxxxx /* aggregate block # */ xad #1: flag 这里不讨论 offset 1016 /* the beginning of the file */ length 1 /* 1 1KB aggregate blocks */ address yyyyy /* aggregate block */ 在该例中,第一个盘区(xad 0)包含字节 "hi",紧接着是 1022 字节 0。最后一个盘区(xad 1)包含 990 字节 0,紧接着是 3 字节 "bye"。1KB 盘区中剩余的 31 字节不是文件的组成部分。(它们与第一个例子中丢失成为内部存储碎片的 31 个字节相同)。 请注意,该例中, xad_offset 字段是必需的;这是知道 xad 1 表示文件内在无法预料的逻辑偏移量字节序列的唯一方法(也即,xad 1 的偏移量不等于 xad 0 的偏移量加长度)。这是表示稀疏文件的方法。 inode 的 di_size 字段包含写入的最后一个字节偏移值加 1。 连续分配的 16GB 的文件: xad 结构中的长度字段仅有 24 位长:因此,它能包含的最大值是 2(24)-1。如果聚集块大小是 1KB(例如),那么一个 xad 能够表示的最大盘区是(2(24)-1)*2(10)=1KB,小于 16G。暗示这也是 xad 结构能够表示的最大盘区。因此,如果文件够大的话,就算它在磁盘上是相连的,也需要多个 xad 结构来表示它。本例中显示了这样一个连续分配的文件:一个 16G 文件,它从聚集块号 12345 开始连续分配,获取 16777216 个 1KB 的聚集块(16G)。 xad #0 :
|