位置:海鸟网 > IT > linux/Unix >

JFS 文件系统概述及布局分析(三)

保留聚集inode5到15以备将来扩展。

从聚集inode16开始,每个文件集有一个inode,即文件集分配映射表inode。这个inode描述了表示文件集的控制结构。当更多文件集添加到聚集中时,为了容纳更多的文件集inode,聚集inode表本身可能必须增大。

分配组

分配组(AG)把聚集中的空间分成大块,并且允许JFS资源分配策略使用众所周知的方法,来实现更好的JFSI/O性能。首先,分配策略尝试将相关数据的磁盘块和磁盘inode集群起来,使磁盘实现好的局域性。文件通常是顺序地读写,而目录中的文件通常一起访问。其次,为了容纳局域性,分配策略尝试在整个聚集中分配不相关数据。聚集内的分配组用从0开始的AG(分配组)索引。即用AG标识。

必须选择分配组大小,以使AG足够大以不断提供连续资源分配。为了将聚集扩充或缩小时所需进行的更新数最小化,分配组必须限制最大组数128。此外,JFS将对8192个聚集块的分配组大小规定其最小值。分配组大小必须总是1个dmap页(1、2、4、8、...dmap页)描述的块数的2的幂次方。分配组大小在聚集超级块中存储。

大小不是分配组大小倍数的聚集将包含部分分配组;磁盘块没有完全覆盖聚集的最后一个分配组。除了JFS将标记在块分配映射表中分配的却不存在的磁盘块之外,该部分分配组将被当作完整的分配组。

文件集

文件集是文件和目录的集合,这些文件和目录形成了可独立安装的子树。文件集完全包含在一个聚集中。请注意,一个聚集中可能有多个文件集;在那种情况下,所有文件集共享由聚集控制结构定义的空闲聚集磁盘块公共池。

文件集有:

文件集inode表,包含描述文件集范围的控制结构的inode。文件集inode表逻辑上包含一个inode数组。

文件集inode分配映射表,描述文件集inode表。文件集inode分配映射表包含文件集inode上及其磁盘位置上的分配状态信息。描述文件集分配映射表和其他文件集信息的超级inode,驻留前面所描述的聚集inode表中。由于复制了聚集inode表,因此这个inode存在第二个版本,它指向同样的数据。超级inode本身是一个文件。当文件集一开始创建时,分配第一个inode盘区按需要动态分配和释放其它inode盘区。

文件集中inode的分配如下所示:

保留文件集inode0。

文件集inode1包含附加的文件集信息,它们无法放入聚集inode表中的文件集分配映射表inode。

文件集inode2是文件集的根目录inode。注意,JFS保留了inode2是文件系统的根这一公共Unix约定。

文件集inode3是文件集的ACL文件。

从文件集inode4开始,文件集inode用于一般文件集对象、用户文件、目录和符号链接。

盘区、inode、B+树

盘区是当作单元分配给JFS对象的连续聚集块序列。盘区完全包含在一个聚集(并且因此也是在一个分区)中;但是,大盘区可能跨多个分配组。

每个JFS对象可用一个inode来表示。inode包含预期的对象特定信息,例如:时间戳和文件类型。它们还包含记录盘区分配的B+树。注意,所有JFS元数据结构(除超级块之外)都以文件表示。通过重用这种数据的inode结构,数据格式(即磁盘布局)自然是可扩展的。

盘区、B+树、inode在以下章节中详细描述。

盘区

文件是按盘区顺序分配的。盘区是当作一个单元分配的聚集块的连续变长序列。盘区的尺寸范围是1到2(24)-1个聚集块。盘区可能跨越多个分配组(AG)。为了在插入新盘区、定位特定盘区等操作方面有更优性能,这些盘区是按B+树索引的。

定义一个盘区需要两个值,即其长度和其地址。长度以聚集块尺寸为单位计算。JFS使用24位值来表示盘区的长度,因此盘区的范围大小是1到2(24)-1个聚集块。

对于512字节的聚集块尺寸(所允许的最小值),最大盘区是512*(2(24)-1)字节,(比8G稍小)。对于4096字节的聚集块尺寸(所允许的最大值),盘区的最大长度是4096*(2(24)-1)字节,(比64G稍小)。这些限制仅适用于一个的盘区;对整体文件大小没有限制作用。地址指的是盘区中第一个块的地址。地址同样以聚集块为单位:它从聚集的开始处计算块偏移量。

结合了用户特定聚集块尺寸的基于盘区的文件系统,允许JFS不需要单独支持内部存储碎片。可配置聚集使用小的聚集块尺寸(例如,512字节),以使大量小尺寸文件的聚集内部存储碎片最小化。

通常,JFS分配尝试通过分配最小数量的盘区策略,而使每个盘区尽可能大。这就允许大的I/O传送,结果使得性能提高。然而,对于特殊情况,不一定总有这种结果。例如,一个段的写入时复制会造成连续盘区被分割成更小的连续盘区系列。另一种情况是盘区大小的限制。例如:由于JFS必须把整个盘区读入内存,然后进行解压缩,所以压缩文件盘区大小是有限的。由于JFS的可用内存数量有限,因此它必须保证有足够的空间用于解压缩盘区。

提供了一个碎片整理实用程序,以减少动态分配/释放可变长盘区时出现的外部存储碎片。这种分配和释放可能导致不相连的变长空闲盘区遍及整个聚集。碎片整理实用程序会把多个小的空闲盘区合并成一个较大的盘区。

inode

JFS磁盘inode是512字节。一个JFS磁盘inode包含4组基本信息。第一组描述JFS对象的POSIX属性。第二组描述JFS对象的其它属性;这些属性包括支持VFS必需的信息、操作系统环境特定的信息、以及B+树的头部。第三组不是包含B+树根节点的盘区分配描述符就是包含内嵌数据。第四组包含扩展属性、更多内嵌数据或附加的盘区分配描述符。在jfs_dinode.h的structdinode中定义磁盘inode结构。

JFS动态分配inode提供的好处如下:

inode磁盘块可放在任何磁盘地址,这使得inode号和位置分开。这种分离简化了支持聚集和文件集重组,能够使聚集缩小。可以移动inode,移动后号码仍然相同。这允许JFS不必需要查找目录结构就可以更新inode号。对于支持DFS文件集复制而言,这种分离也是必需的。当复制文件集时,仅复制inode。既然JFS能把新的inode放在磁盘的任意位置,新inode将有与从它们复制的inode相同的号码。这允许JFS不需复制目录结构并且更新inode号。

不再需要分配实际所需十倍的inode。这对于JFS中较大的inode尺寸(大于512字节)而言,尤为重要。

大文件的文件分配可能消耗多个分配组且仍是连续的,而静态分配造成间隔(由于每个分配组中初始分配的inode)。

另一方面,动态inode分配造成大量问题,包括:

对于静态分配,文件系统的几何构造隐含描述了磁盘上inode的布局;对于动态分配,必需有单独的映射结构。

对JFS完整性而言,这些映射结构是至关重要的。由于复制这些结构的系统开销,JFS决定接受丢失这些映射表的风险。但是,JFS将复制B+树结构,该结构允许JFS查找映射表。

通过只分配磁盘上inode连续大块的inode盘区,动态分配了inode。根据定义,一个JFSinode盘区包含32个inode。对于512字节的inode尺寸,因此磁盘上一个inode盘区的大小是16KB。

当分配新的inode盘区时,并不初始化盘区。然而,要使fsck能够检查是否inode在使用中,JFS需要inode的一些信息。一旦盘区中的inode标记成在使用中,就必须初始化它的文件集号、inode号、inode戳以及inode分配组块地址。因此,链接字段就足以确定inode当前是否正在使用。

注意,动态inode分配意味着在inode号与inode的磁盘地址之间没有直接关系。因此,JFS必须有查找磁盘上inode的方法。inode分配映射表提供了这一功能。

inode生成号只是每当重用inode时值就增加的计数器。

存储每个inode生成计数器这一静态inode分配常用方法在动态inode分配中不起作用,因为当inode空闲时,其磁盘空间可能确实由不是inode的数据所重用,(换句话说,空间可能被收回,以存储普通文件数据)。因此,在JFS中,只有一个inode生成计数器,它在每一个inode分配时增加其值,即在重用inode时,相应的计数器增加其值,而不是每个inode有一个计数器。