flag 这里不讨论 offset 0 /* the beginning of the file */ length 16777215 /* 1 1KB aggregate blocks */ address 12345 /* aggregate block */xad #1: flag 这里不讨论 offset 16777215 /* the beginning of the file */ length 1 /* 1 1KB aggregate blocks */ address 16789560 /* aggregate block # */ 在该例中,不论文件在磁盘上是否相连,要表示它至少需要两个 xad 结构,这是由于单个盘区的长度限制。 [page_break] 块分配映射表 块分配映射表用来为整个聚集跟踪分配或释放的磁盘块。由于聚集内所有的文件集共享相同的磁盘块池,在分配或释放磁盘块时,聚集内所有的文件集可使用该分配映射表。 块分配映射表本身是聚集 inode 2 描述的文件。当初始创建聚集时,分配包括聚集空间的映射表数据块。映射表将随着聚集的扩充或紧缩而相应动态地增大或缩小。 块分配映射表跟踪是否每个个别的聚集块被分配还是释放。 映射表的每页长度为 4K。映射表包含三种类型的页:bmap 控制页、dmap 控制页和 dmap 页。 每个 dmap 包含表示每个聚集块的一位。第 i 位表示第 i 个逻辑聚集块的分配状态。它由 struct dmap_t 的 jfs_dmap.h 文件定义。每个 dmap 页包括 8K 的聚集块。 因为块分配映射表可能有许多 dmap 页,它们由 dmap 控制页组织。这些页改进了查找空闲块的大盘区的性能。聚集的大小将决定需要多少页和多少层。至多有三层,它允许的聚集块的最大尺寸是 2(43)。如果不是所有层都需要,块映射表 inode 是每个没有使用层的第一页有“洞”的稀疏文件。 JFS 使用提交策略确保控制数据可靠更新。可靠更新意味着一旦系统出错时,要维持一致的 JFS 结构和资源分配状态。为了保证块分配映射表是一致状态,JFS 维护 dmap 结构中的两张映射表,工作映射表和持续映射表。工作映射表记录当前分配状态。持续映射表记录提交的分配状态,由磁盘上找到的或 JFS 日志或提交的 JFS 事务内的记录描述的分配状态组成。当释放聚集块时,首先更新永久映射表。当分配聚集块时,首先更新工作映射表。位值为 0 表示空闲资源,值为 1 表示已分配资源。 块分配映射表的 dmap 控制页包含与 dmap 结构中树相似的树,除叶层包含 1024 个元素外。dmap 控制页由 struct dmapctl_t 定义。可在 jfs_dmap.h.文件中找到它。 要注意,dmap 结构中的这一字段是一个平面数组,但它表示图中显示的树。树跟踪除最底层之外的每层上连续块的最大号。树的最底层,从树 [85] 到树 [341],包含下面描述的工作映射表的二进制搭档表示法。树的其它层包含来自下一较低层的四个部分的最大数目相连空闲块。 二进制搭档系统用来完成每个摘要树的叶层。通过首先为位图的每个字获得空闲位的最长二进制搭档字符串而形成 dmap 结构的树。字符以 2 的幂编码,-1 用来表示已分配全部。 然后,使用二进制搭档系统完成树的叶。通过取得从指定索引开始、只包括其以 2 的幂显示的搭档的最大数目空闲块,可形成此树。 请注意,只有完全空闲的字才与其完全空闲的搭档组合。组合时,最右搭档变成 -1,以指示它由另一项所表示。 块分配映射表的 dmap 控制页包含与 dmap 结构中树相似的树,除叶层包含 1024 个元素外。这些元素是树 [0] 为紧跟下面的 1024 个映射表页的二进制搭档表示法。对于 L0 页,它是接下来的 1024 个 dmap 页,对于 L1 页,它是接下来的 1024 个 L0 页,而对于 L2 页,它是接下来 1024 个 L1 页。 在块分配映射表的顶部,有映射表控制结构 structdbmap_t 。该结构包含摘要信息,能加快查找比平均空闲空间多的 AG。可在 jfs_dmap.h 中找到该结构。 块分配映射表没有记日志:它能在恢复期间由 logredo 修复,或者由 fsck 重构。在 fsck 或 logredo 后工作和持续映射表,都必需是相同状态。 扩展聚集以增大文件系统 要扩展聚集,JFS 必须确保有足够的页存储块分配映射表, 索引聚集新扩展的块。通常,从现有的聚集分配空间给新增的页,但是如果该聚集空间已满,那就不可能了。所以我们需要解决这种特殊情况。 要解决该问题,通常 JFS 为块分配映射表分配的空间多于索引聚集地址空间所需的空间。每个映射表都有额外页空间用于存放位图,如果该页指向另一层摘要树,则该映射表就需额外页存放所需的摘要信息。这种额外空间使得 JFS 可以在必要时将聚集分为更小的单位,以扩大聚集至所需的大小。扩展聚集,需采取以下步骤: 如果现有聚集的空间足以扩展块分配映射表,使其能索引新聚集的所有块,那么,JFS 不做任何特殊处理,将聚集扩展至整个空间。仅当需要考虑聚集将来的扩展时,块分配映射表才需增加额外页。 如果没有足够空间扩展,那么 JFS 仅给聚集扩展块分配映射表中已有额外页所能寻址的块。 至此,JFS 有一些额外的聚集块未在聚集中使用到。JFS 可以用这些聚集块扩大块分配映射表,以继续将聚集扩展至所需大小。JFS 必须谨记将这些额外页放入块分配映射表中。 这个处理过程完全由 vfs_cntl() 处理,对系统的其它部分隐藏。 另一种表示法:二进制编码搭档表示法 块分配映射表也可以用二进制编码搭档系统表示。除了树的叶结点和 dmap 结构不同外,这种表示法的逻辑和物理结构与前一种一样。 struct dmap 定义块分配映射表的最下层。每个 dmap 页包括 8K 的聚集块。 /* * dmap summary tree * * dmaptree_t must be consistent with dmapctl_t. */ typedef struct { int32 nleafs; /* 4: number of tree leafs */
|