Xfs文件系统磁盘布局之八:ABTB/ABTC的节点块管理
前面几篇文章都是描述的如何利用ABTB/ABTC类型的B+tree来对AG空闲磁盘空间块进行管理,而这篇文章主要讲对ABTB/ABTC类型的B+tree各个节点本身所占去的磁盘block块的管理。
前面提到过,一块刚建立的Xfs文件系统,AG(仍然是以primary AG为例)的第1块block和第2块block分别被用来作为了ABTB和ABTC类型的B+tree的根节点,并且保留了第4、5、6、7这4块block作为B+tree增长所需。再来看一下:
[root@localhost ~]# /home/lenky/xfs/xfsprogs/db/xfs_db /dev/loop0
xfs_db> agf
xfs_db> p
magicnum = 0x58414746
versionnum = 1
seqno = 0
length = 32768
bnoroot = 1
被ABTB类型的B+tree根节点占去的第1块block。
cntroot = 2
被ABTC类型的B+tree根节点占去的第2块block。
bnolevel = 1
cntlevel = 1
flfirst = 0
fllast = 3
flcount = 4
freeblks = 32756
longest = 32756
btreeblks = 0
xfs_db> agfl
xfs_db> p
bno[0-127] = 0:4 1:5 2:6 3:7
为ABTB/ABTC类型的B+tree增长所需而保留下来的第4、5、6、7这4块block。
xfs_db>
保留下来的block的块号被记录在agfl里,前面文章的图示中给出过agfl的位置,即是在第0块block的第3个sector内:
[root@localhost loop]# hexdump -C -s 1536 -n 512 /dev/loop0 00000600 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 07 |................| 00000610 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000800 [root@localhost loop]#
一个sector大小为512,而指示一个block号需要4个字节,所以agfl总共可以保存128块block的块号,也即是上面的bno[0-127]被显示为一个具有128个元素的数组。agfl内指定的block并不全是有效的,有一些block可能已经被当作BTB/ABTC类型的B+tree节点使用,也可能已经释放或做它用,只有一部分有效,哪些有效呢?agf里的三个字段(flfirst、fllast和flcount)指明了这一点,即是bno[flfirst]到bno[fllast],这flcount个元素指定的block块才是有效的,值得注意的是,bno被组成了一个环状,也就是说如果flfirst=126,fllast=1,flcount=4,那么有效block的块号分别为bno[126]、bno[127]、bno[0]、bno[1]。这些保留下来的有效的block块不能用来保存任何其它数据,只能用来作为当ABTB/ABTC类型的B+tree增长需要新的中间节点或叶子节点的存储空间。保留block块的申请释放在函数xfs_alloc_fix_freelist内,被释放出保留队列的block块当然就可以用来存放其它数据了。
看实际数据验证我们的分析:
[root@localhost xfsprogs]# ./db/xfs_db /dev/sdb1 xfs_db> agf 0 xfs_db> p magicnum = 0x58414746 versionnum = 1 seqno = 0 length = 262059 bnoroot = 5 cntroot = 472 bnolevel = 2 cntlevel = 2 flfirst = 21 fllast = 26 flcount = 6 freeblks = 165395 longest = 86535 btreeblks = 16 xfs_db> agfl xfs_db> p bno[0-127] = 0:4 1:5 2:6 3:7 4:470 5:471 6:472 7:473 8:474 9:475 10:6 11:7 12:58 13:138 14:139 15:106 16:108 17:110 18:134 19:160 20:324 21:407 22:419 23:421 24:64 25:134 26:99 xfs_db> fsblock 5 xfs_db> type bnobt xfs_db> p magic = 0x41425442 level = 1 numrecs = 8 leftsib = null rightsib = null keys[1-8] = [startblock,blockcount] 1:[32,3] 2:[47931,66] 3:[70425,1] 4:[75668,2] 5:[99725,12] 6:[139125,51] 7:[151459,3] 8:[153765,1] ptrs[1-8] = 1:1 2:324 3:4 4:473 5:6 6:138 7:139 8:110 xfs_db> fsblock 472 xfs_db> type cntbt xfs_db> p magic = 0x41425443 level = 1 numrecs = 8 leftsib = null rightsib = null keys[1-8] = [blockcount,startblock] 1:[1,107] 2:[1,115863] 3:[1,152036] 4:[2,115332] 5:[3,76899] 6:[4,77297] 7:[8,77161] 8:[24,73665] ptrs[1-8] = 1:2 2:474 3:106 4:471 5:108 6:58 7:475 8:7 xfs_db>
ABTB占用的块:
1、4、5、6、110、138、139、324、473
ABTC占用的块:
2、7、58、106、108、471、472、474、475
保留队列:
0:4 1:5 2:6 3:7 4:470 5:471 6:472 7:473 8:474 9:475 10:6 11:7 12:58 13:138 14:139 15:106 16:108 17:110 18:134 19:160 20:324 21:407 22:419 23:421 24:64 25:134 26:99
红色字体block块是当前做为ABTB/ABTC类型的B+tree节点在使用的,一共有16块,符合上面btreeblks的值(这个字段记录ABTB和ABTC这两种类型B+tree的树节点所占的block块数,但不包括最开始根节点所占的那两块,即是第1块和第2块),蓝色字体block当前是处于保留状态,而绿色字体block是之前做过保留、被当作B+tree节点使用之后,现在已被释放,但释放的134这块block现在又处于了保留状态。
xfs_db> fsblock 470 xfs_db> type text xfs_db> p 000: 52 43 55 20 61 6e 64 20 55 6e 6c 6f 61 64 61 62 RCU.and.Unloadab 010: 6c 65 20 4d 6f 64 75 6c 65 73 0a 0a 5b 4f 72 69 le.Modules...Ori 020: 67 69 6e 61 6c 6c 79 20 70 75 62 6c 69 73 68 65 ginally.publishe 030: 64 20 69 6e 20 4c 57 4e 20 4a 61 6e 2e 20 31 34 d.in.LWN.Jan..14 040: 2c 20 32 30 30 37 3a 20 68 74 74 70 3a 2f 2f 6c ..2007..http...l * ff0: 20 20 20 20 20 20 20 22 53 74 6f 70 70 69 6e 67 ........Stopping xfs_db> fsblock 160 xfs_db> type text xfs_db> p 000: 0a 50 6f 77 65 72 4e 6f 77 21 20 61 6e 64 20 43 .PowerNow..and.C 010: 6f 6f 6c 27 6e 27 51 75 69 65 74 20 61 72 65 20 ool.n.Quiet.are. 020: 41 4d 44 20 6e 61 6d 65 73 20 66 6f 72 20 66 72 AMD.names.for.fr 030: 65 71 75 65 6e 63 79 0a 6d 61 6e 61 67 65 6d 65 equency.manageme 040: 6e 74 20 63 61 70 61 62 69 6c 69 74 69 65 73 20 nt.capabilities. * ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ xfs_db> fsblock 134 xfs_db> type text xfs_db> p 000: 41 42 54 42 00 00 00 ff 00 00 00 01 00 00 00 04 ABTB............ 010: 00 00 bb 3b 00 00 00 42 00 00 bd 26 00 00 00 2d .......B........ 020: 00 00 bd c4 00 00 00 05 00 00 be 09 00 00 00 0a ................ 030: 00 00 be 7b 00 00 00 37 00 00 bf 61 00 00 00 02 .......7...a.... 040: 00 00 c0 19 00 00 00 72 00 00 c0 96 00 00 00 6d .......r.......m * ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ xfs_db>
一定程度上可以看到470和160这两块block已经放了数据(不能确定这些数据当前是否有效,但可以确定其一定没有作为B+tree节点在使用),而134这块block被保留下来了(可以确定其当前一定没有存放其它有效数据)。
转载请保留地址:http://www.lenky.info/archives/2012/01/759 或 http://lenky.info/?p=759
备注:如无特殊说明,文章内容均出自Lenky个人的真实理解而并非存心妄自揣测来故意愚人耳目。由于个人水平有限,虽力求内容正确无误,但仍然难免出错,请勿见怪,如果可以则请留言告之,并欢迎来信讨论。另外值得说明的是,Lenky的部分文章以及部分内容参考借鉴了网络上各位网友的热心分享,特别是一些带有完全参考的文章,其后附带的链接内容也许更直接、更丰富,而我只是做了一下归纳&转述,在此也一并表示感谢。关于本站的所有技术文章,欢迎转载,但请遵从CC创作共享协议,而一些私人性质较强的心情随笔,建议不要转载。
法律:根据最新颁布的《信息网络传播权保护条例》,如果您认为本文章的任何内容侵犯了您的权利,请以Email或书面等方式告知,本站将及时删除相关内容或链接。
@Conan
根据文件名算出hash value,然后根据hash value从根目录的目录项开始查找,查找到该目录项后,然后读取目录项中的inode号,根据inode号算出该文件的inode所在位置,找到该位置读取inode中的extent指针来获取该文件的文件内容。 这个涉及到博主写的目录的目录项在底层的数据分布情况,博主写的很详细,
你好,Lenky。看过你写的描述 XFS 文件系统布局的文章,受益匪浅,在此现行谢过!另外,想请教一个问题,你描述的布局大都是讲解如何快速和有效的找到磁盘空闲空间,如逻辑块号,逻辑块数与 inode 号等。这些信息对用户写数据时当然帮助很大,但是如果用户想要从成千上百万的文件里读出其想要的文件时,那么 XFS 文件系统是如何做到的?这部分貌似你的博客文章里没有讲哈。