JFS 文件系统概述及布局分析(5)
核心提示:块分配映照表用来为全部聚集跟踪分配或开释的磁盘块。由于聚集内所有的文件集共享相同的磁盘块池,在分配或开释磁盘块时,聚集内所有的文件集可使用该分配映照表。
块分配映照表
块分配映照表用来为全部聚集跟踪分配或开释的磁盘块。由于聚集内所有的文件集共享相同的磁盘块池,在分配或开释磁盘块时,聚集内所有的文件集可使用该分配映照表。
块分配映照表本身是聚集inode2描写的文件。当初始创建聚集时,分配包括聚集空间的映照表数据块。映照表将随着聚集的扩充或紧缩而相应动态地增大或缩小。
块分配映照表跟踪是否是每个个别的聚集块被分配还是开释。
映照表的每页长度为4K。映照表包括3种类型的页:bmap控制页、dmap控制页和dmap页。
每个dmap包括表示每个聚集块的1位。第i位表示第i个逻辑聚集块的分配状态。它由structdmap_t的jfs_dmap.h文件定义。每个dmap页包括8K的聚集块。
由于块分配映照表可能有很多dmap页,它们由dmap控制页组织。这些页改进了查找空闲块的大盘区的性能。聚集的大小将决定需要多少页和多少层。最多有3层,它答应的聚集块的最大尺寸是2(43)。假设不是所有层都需要,块映照表inode是每个没有使用层的第1页有“洞”的稀疏文件。
JFS使用提交策略确保控制数据可靠更新。可靠更新意味着1旦系统出错时,要保持1致的JFS结构和资源分配状态。为了保证块分配映照表是1致状态,JFS保护dmap结构中的两张映照表,工作映照表和延续映照表。工作映照表记录当前分配状态。延续映照表记录提交的分配状态,由磁盘上找到的或JFS日志或提交的JFS事务内的记录描写的分配状态组成。当开释聚集块时,首先更新永久映照表。当分配聚集块时,首先更新工作映照表。位值为0表示空闲资源,值为1表示已分配资源。
块分配映照表的dmap控制页包括与dmap结构中树类似的树,除叶层包括1024个元素外。dmap控制页由structdmapctl_t定义。可在jfs_dmap.h.文件中找到它。
要留意,dmap结构中的这1字段是1个平面数组,但它表示图中显示的树。树跟踪除最底层之外的每层上连续块的最大号。树的最底层,从树[85]到树[341],包括下面描写的工作映照表的2进制搭档表示法。树的其它层包括来自下1较低层的4个部份的最大数目相连空闲块。
2进制搭档系统用来完成每个摘要树的叶层。通过首先为位图的每个字取得空闲位的最长2进制搭档字符串而构成dmap结构的树。字符以2的幂编码,⑴用来表示已分配全部。
然后,使用2进制搭档系统完成树的叶。通过取得从指定索引开始、只包括其以2的幂显示的搭档的最大数目空闲块,可构成此树。
请留意,只有完全空闲的字才与其完全空闲的搭档组合。组合时,最右搭档变成⑴,以唆使它由另1项所表示。
块分配映照表的dmap控制页包括与dmap结构中树类似的树,除叶层包括1024个元素外。这些元素是树[0]为紧跟下面的1024个映照表页的2进制搭档表示法。对L0页,它是接下来的1024个dmap页,对L1页,它是接下来的1024个L0页,而对L2页,它是接下来1024个L1页。
在块分配映照表的顶部,有映照表控制结构structdbmap_t。该结构包括摘要信息,能加快查找比均匀空闲空间多的AG。可在jfs_dmap.h中找到该结构。
块分配映照表没有记日志:它能在恢复期间由logredo修复,或由fsck重构。在fsck或logredo后工作和延续映照表,都必须是相同状态。
扩大聚集以增大文件系统
要扩大聚集,JFS必须确保有足够的页存储块分配映照表,索引聚集新扩大的块。通常,从现有的聚集分配空间给新增的页,但是假设该聚集空间已满,那就不可能了。所以我们需要解决这类特殊情况。
要解决该题目,通常JFS为块分配映照表分配的空间多于索引聚集地址空间所需的空间。每个映照表都有额外页空间用于寄存位图,假设该页指向另1层摘要树,则该映照表就需额外页寄存所需的摘要信息。这类额外空间使得JFS可以在必要时将聚集分为更小的单位,以扩大聚集至所需的大小。扩大聚集,需采取以下步骤:
假设现有聚集的空间足以扩大块分配映照表,使其能索引新聚集的所有块,那末,JFS不做任何特殊处理,将聚集扩大至全部空间。仅当需要考虑聚集将来的扩大时,块分配映照表才需增加额外页。
假设没有足够空间扩大,那末JFS仅给聚集扩大块分配映照表中已有额外页所能寻址的块。
至此,JFS有1些额外的聚集块未在聚集中使用到。JFS可以用这些聚集块扩大块分配映照表,以继续将聚集扩大至所需大小。JFS必须谨记将这些额外页放进块分配映照表中。
这个处理进程完全由vfs_cntl()处理,对系统的其它部份隐躲。
另1种表示法:2进制编码搭档表示法
块分配映照表也能够用2进制编码搭档系统表示。除树的叶结点和dmap结构不同外,这类表示法的逻辑和物理结构与前1种1样。
structdmap定义块分配映照表的最下层。每个dmap页包括8K的聚集块。
以下为援用的内容: /* *dmapsummarytree * *dmaptree_tmustbeconsistentwithdmapctl_t. */ typedefstruct{ int32nleafs;/*4:numberoftreeleafs*/ int32l2nleafs;/*4:l2numberoftreeleafs*/ int32leafidx;/*4:indexoffirsttreeleaf*/ int32height;/*4:heightofthetree*/ int8budmin;/*1:minl2treeleafvaluetocombine*/ int8stree[TREESIZE];/*TREESIZE:tree*/ uint8pad[2];/*2:padtowordboundary*/ }dmaptree_t;/*⑶60-*/ /* *dmappageper8Kblocksbitmap */ typedefstruct{ int32nblocks;/*4:numblkscoveredbythisdmap*/ int32nfree;/*4:numoffreeblksinthisdmap*/ int64start;/*8:startingblknoforthisdmap*/ dmaptree_ttree;/*360:dmaptree*/ uint8pad[1672];/*1672:padto2048bytes*/ uint32wmap[LPERDMAP];/*1024:bitsoftheworkingmap*/ uint32pmap[LPERDMAP];/*1024:bitsofthepersistentmap*/ }dmap_t;/*⑷096-*/ |
2进制编码搭档系统的每1项都有3个字段:type,size和bitmap。type字段表示块空闲、已分配、用位图表示或不由该字段表示(don'tcare)。假设类型是"don'tcare"则这些块由左搭档表示,size字段忽视。假设type是位图,则位图字段的32位和32块逐1对应,表示其空闲或已分配。位值0表示空闲块,1表示块已分配。size是2的幂次方,表示该项描写的聚集块的个数。
对每个全空闲项,假设其相同大小的左搭档也完全空闲,则右搭档设为"don'tcare"类型,且右搭档的空间合并进左搭档。当分配块时,仅当搭档分配在同1盘区才合并。必须保护"don'tcare"类型,以便logredo修正映照表。
结构dmap包括1个摘要树。其它每个映照层都包括1个摘要树。摘要树进步了查找空闲块大盘区的性能。摘要信息足以判定dmap页是否是有足够的空闲位,这样就无需查看dmap页,从而可以免无效搜索。
要留意,dmap结构中的这1字段是1个平面数组,但它表示图中显示的树。树的每1层都索引最大数目个相邻的块。树的最底层,树[21]至树[84],映照至工作映照表中的2进制编码搭档表示。树的其它层包括来自下1较低层的4个部份的最大数目相连空闲块。块分配映照表的其它层可能有1个类似的树,除叶节点层有1024个元素。这些元素映照至树[0]的2进制编码搭档表示,树[0]指向后面的dmap页。
假设要合并的4个都为"don'tcare"类型,则合并项大小标记为⑴。这些项的搭档项负责标记正确的状态。
inode分配
动态inode分配机制中,inode号不再直接映照至聚集中特定的逻辑磁盘块,所以要支持以下3种操纵,需要定义新的数据结构:
正向查找:给定inode号,找到磁盘上的inode。文件查找是1种典型的正向查找。
反向查找:给定分区磁盘号(更肯定,则给定分配组号),查找邻近的空闲i-结点。分配新inode就属于这类情况,JFS尽可能查找物理上邻近所选分配组的inode(以便,例如,同1子目录的文件其inode都是相邻的)。
空闲inode号查找:要分配新的inode盘区,先要找到32个相邻的、未分配给相应inode盘区的inode。当所有已分配的inode都在使用,或当JFS需要给分配组分配inode但之前从未分配过inode时,或当1个分配组中没有空闲inode时,需要分配新的inode盘区。
留意动态inode分配的1种奥妙效应:相邻inode号在磁盘上未必相邻:inodeN+32可以和inodeN相隔任意远。但是,相隔很远的inode号在磁盘上可以是紧邻的;所以,inodeN+K和inodeN紧邻在理论上是可能的(即使K>1)
inode分配映照表
inode分配映照表解决正向查找题目。聚集和每个文件集都有1个inode分配映照表,该表是1个IAG(inode分配组)的数组。IAG是inode分配映照表的数据。对聚集,inode分配映照表映照的inode也称为聚集inode表。对文件集,inode分配映照表映照的inode也称为文件inode表。
每个IAG大小为4K,描写磁盘上128个物理inode盘区。由于每个inode盘区包括32个inode,所以每个IAG描写4096个inode。IAG可以位于聚集的任意位置。IAG的所有inode盘区位于1个分配组,由此IAG和AG绑定在1起直至开释所有的inode盘区。任意AG可以分配空间给1个inode盘区,然后该IAG就与那个AG绑定。IAG由structiag_t定义(见jfs_imap.h)。
以下为援用的内容: /* *inodeallocationgrouppage(per4096inodesofanAG) */ typedefstruct{ int64agstart;/*8:startingblockofag*/ int32iagnum;/*4:inodeallocationgroupnumber*/ int32inofreefwd;/*4:aginodefreelistforward*/ int32inofreeback;/*4:aginodefreelistback*/ int32extfreefwd;/*4:aginodeextentfreelistforward*/ int32extfreeback;/*4:aginodeextentfreelistback*/ int32iagfree;/*4:iagfreelist*/ /*summarymap:1bitperinodeextent*/ int32inosmap[SMAPSZ];/*16:summapofmapwordsw/freeinodes; *note:thisindicatesfreeandbacked *inodes,iftheextentisnotbackedthe *valuewillbe1.iftheextentis *backedbutallinodesarebeingusedthe *valuewillbe1.iftheextentis *backedbutatleastoneoftheinodesis *freethevaluewillbe0. */ int32extsmap[SMAPSZ];/*16:summapofmapwordsw/freeextents*/ int32nfreeinos;/*4:numberoffreeinodes*/ int32nfreeexts;/*4:numberoffreeextents*/ /*(72)*/ uint8pad[1976];/*1976:padto2048bytes*/ /*allocationbitmap:1bitperinode(0-free,1-allocated)*/ uint32wmap[EXTSPERIAG];/*512:workingallocationmap*/ uint32pmap[EXTSPERIAG];/*512:persistentallocationmap*/ pxd_tinoext[EXTSPERIAG];/*1024:inodeextentaddresses*/ }iag_t;/*(4096)*/ |
inode分配映照表最前面4k大小的页是控制页。该页包括inode分配映照表的摘要信息。dinomap_t结构的定义见jfs_imap.h。
逻辑上,inode分配映照表是动态可扩大的IAG结构的数组:
structiaginode_allocation_map[1..N];
物理上,inode分配映照表本身是聚集内的1个文件。聚集inode分配映照表由聚集self-node描写。文件集inode分配映照表由文件集inode描写。页空间的分配和开释根据B+树索引需要进行。B+树的键是IAG页的字节偏移量。
JFS使用提交策略确保控制数据可靠更新。可靠更新意味着1旦系统出错时,要保持1致的JFS结构和资源分配状态。为确保inode分配映照表的1致性,每个IAG都同时保护两个映照表,工作映照表和延续映照表。工作映照表记录当前分配状态。延续磁盘记录递交的分配状态,包括磁盘上记录的分配状态或是JFS日志中提交的JFS事务记录描写的分配状态。
映照表中的每1位记录相应inode是空闲还是已分配的。位值0表示inode空闲,1表示inode已分配。IAG的每1个控制区内都有1个摘要映照表,用以进步查找空闲inode的性能。摘要映照表映照到IAG的工作位图。摘要映照表使用1位映照工作映照表的相邻32位。每1位表示相应的inode可用(0),或相应的inode不可用(1)。(假设没有已分配的盘区,那末该inode摘要映照位为1,表明没有可用的inode,)
IAG还包括inode盘区描写符,该描写符描写相应的inode盘区。每个IAG有128个描写符。IAG的每个控制区内都有1个摘要映照表,用于改进空闲inode盘区查找的性能。摘要映照表用1位映照1个inode盘区。0表示空闲的inode盘区,1表示已分配的inode盘区。
假设给定inode号,用inode分配映照表,通过以下步骤,可以找到inode的物理位置:
1、找到描写该inode的IAG。需要找到inode分配映照表在B+树中的键(字节偏移量)。
iagkey=((Inodenumber/Inodesperiag)*Inodesperiag)+4096(EQ1)
2、查找已找到的IAG中援用的inode。这可用于在IAG工作映照表和延续映照表中索引。
iaginodeindex=(Inodenumber)mod(Inodesperiag)(EQ2)
3、查找IAG中的inode盘区描写符,该描写符描写包括指定inode的inode盘区。
inodeextentdescriptor=(iaginodeindex)/(Inodeperinodeextent)(EQ3)
4、要找的inode位于找到的inode盘区内、适当的偏移量处。
inodeoffset=((iaginodeindex)mod(Inodesperinodeextent)
*sizeofdinode)(EQ4)
inode分配映照表本身由聚集inode表中文件集的分配映照表inode描写。
通过前面先容的公式,将inode号,#9157,转换成1个偏移量:
以下为援用的内容: iagkey=((inum/num_inodes_per_iag)*(num_inodes_per_iag))+4096 =((9157/4096)*4096)+4096 =12288 iaginodeindex=inummodnum_inodes_per_iag =(9157mod4096) =965 inodeextentdescriptor=iag_inode_index/num_inodes_per_extent =965/32 =30 inodeoffset=(iag_inode_indexmodnum_inodes_per_extent) *sizeofdinode =(965mod32)*512 =5*512 =2560 |
为简化JFS保护命令,及便于理解布局策略的动态性,inode分配映照文件盘区的大小总为4KB。
当新文件集创建时,必须分配1个IAG和第1个inode盘区,以处理文件集的元数据文件。(即,保存的inode和根目录inode)。
AG空闲inode列表
AG空闲inode列表解决反向查找题目。为减少扩大和缩减聚集的系统开消,JFS设定每个聚集答应的最大AG数。所以,AG空闲inode列表头的个数是固定的。列表头在inode分配映照表的控制页中。表的第i项是1个双向列表的头,表的第i项是1个双向列表的头,该双向列表是第i个AG中的所有包括空闲inode的inode分配映照表项(IAG)的集合。IAG号作为列表索引。⑴表示列表尾。每个IAG控制区都包括指向该列表的正向和反向指针。
AG列表从表头开始插进。当分配新的inode盘区,或当因盘区占满而删除1个inode时,会有插进操纵。当1个IAG所有的inode盘区都满时,从列表中删除该IAG。
留意AG3中的IAG没有任何相应的inode盘区可供分配。所以,这些inode未在AG空闲inode列表中表示。
此表没有记日志;但可以在恢复时由logredo恢复,或由fsck重建。AG空闲列表结构定义是structdinomap_t,见jfs_imap.h文件。
唐山网站建设www.fw8.netTAG:文件,磁盘,分配,结构,搭档
评论加载中...
|