还记得在上一章中,我们提到过的结构体struct ext4_extent_idx。这个结构体表示在extent tree中的节点。 我们在前面的章节已经阐述过,ext4使用extent取代了传统的block映射方式。我们的案例中只展示了只有一个extent的情况。本篇文章将介绍多个extent情况下的具体细节。
在本文中,我们选取了文件/var/log/messages,它是系统日志的记录文件,由于它的角色特殊,时间长了会造成给很多的碎片。我们还是先看看他的inode,方法和(一)中描述的一致,在此不重复了。
|
0000c00: 8081 0000 d036 0000 814b ee50 7f4b ee50 .....6...K.P.K.P 0000c10: 7f4b ee50 0000 0000 0000 0100 2000 0000 .K.P........ ... 0000c20: 0000 0800 0100 00000af3 0400 0400 0000 ................ 0000c30: 0000 0000 0000 0000 0100 0000 58c2 0b00 ............X... 0000c40: 0100 0000 0100 0000 e599 1b00 0200 0000 ................ 0000c50: 0100 0000 41e6 2f00 0300 0000 0100 0000 ....A./......... 0000c60: b878 1c00 275f ea72 0000 0000 0000 0000 .x..'_.r........ 0000c70: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000c80: 1c00 0000 c018 94d1 c018 94d1 c0e5 ea86 ................ 0000c90: 9bea e850 d0a4 fcb4 0000 0000 0000 02ea ...P............ 0000ca0: 0706 4000 0000 0000 1f00 0000 0000 0000 ..@............. 0000cb0: 7365 6c69 6e75 7800 0000 0000 0000 0000 selinux......... 0000cc0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000cd0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000ce0: 7379 7374 656d 5f75 3a6f 626a 6563 745f system_u:object_ 0000cf0: 723a 7661 725f 6c6f 675f 743a 7330 0000 r:var_log_t:s0..
|
从0x0af3开始,这是extent header起始的标记,我们还是像(一)那样,对照着表看
|
偏移 |
大小 |
名称 |
描述 |
|
0x0 |
0xf30a |
eh_magic |
幻数magic number, 0xF30A. |
|
0x2 |
0x0004 |
eh_entries |
区段数. |
|
0x4 |
0x0004 |
eh_max |
最大的区段数. |
|
0x6 |
0x0000 |
eh_depth |
段节点在段数中的深度。0则表示为叶子节点,指向数据块;否则指向其它段节点。 |
|
0x8 |
0x0000 |
eh_generation |
暂不讨论 |
因为这里看到depth为0,说明extent中指向的是数据块。在extent header中接下来的将extent是我们把接下来的数据对应到它的表中
|
偏移 |
大小 |
名称 |
描述 |
|
0x0 |
0x0000 0000 |
ee_block |
此区段的第一个块号,起始块号 |
|
0x4 |
0x0001 |
ee_len |
区段内包含的块数. |
|
0x6 |
0x0000 |
ee_start_hi |
此区段所指向的块号(高16位) |
|
0x8 |
0x000b c258 |
ee_start_lo |
此区段所指向的块号(低32位) |
接下来的12个字节
|
偏移 |
大小 |
名称 |
描述 |
|
0x0 |
0x0000 0001 |
ee_block |
此区段的第一个块号,起始块号 |
|
0x4 |
0x0001 |
ee_len |
区段内包含的块数. |
|
0x6 |
0x0000 |
ee_start_hi |
此区段所指向的块号(高16位) |
|
0x8 |
0x001b 99e5 |
ee_start_lo |
此区段所指向的块号(低32位) |
再接下来的12个字节
|
偏移 |
大小 |
名称 |
描述 |
|
0x0 |
0x0000 0002 |
ee_block |
此区段的第一个块号,起始块号 |
|
0x4 |
0x0001 |
ee_len |
区段内包含的块数. |
|
0x6 |
0x0000 |
ee_start_hi |
此区段所指向的块号(高16位) |
|
0x8 |
0x00f2 e641 |
ee_start_lo |
此区段所指向的块号(低32位) |
最后的12个字节
|
偏移 |
大小 |
名称 |
描述 |
|
0x0 |
0x0000 0003 |
ee_block |
此区段的第一个块号,起始块号 |
|
0x4 |
0x0001 |
ee_len |
区段内包含的块数. |
|
0x6 |
0x0000 |
ee_start_hi |
此区段所指向的块号(高16位) |
|
0x8 |
0x001c 78b8 |
ee_start_lo |
此区段所指向的块号(低32位) |
可以通过使用blkcat看到4个块刚好凑成了messages文件,疑心重的同学可以把4个块拼成一个文件,用md5sum比较一下。这里我们并没有想看到extent中的内部节点情况。没关系,我们系统日志文件时会随着时间增长。正在笔者撰写此文时,messages已经变大了,并且超过了16k的大小,也就是超出了4个块。这时候我们看看messages的inode信息,方法不重复了。
|
0000c00: 8081 0000 4f51 0000 eb84 ef50 ea84 ef50 ....OQ.....P...P 0000c10: ea84 ef50 0000 0000 0000 0100 3800 0000 ...P........8... 0000c20: 0000 0800 0100 00000af3 0100 0400 0100 ................ 0000c30: 0000 0000 0000 0000 7c03 1c00 0000 0b00 ........|....... 0000c40: 0100 0000 0100 0000 e599 1b00 0200 0000 ................ 0000c50: 0100 0000 41e6 2f00 0300 0000 0100 0000 ....A./......... 0000c60: b878 1c00 275f ea72 0000 0000 0000 0000 .x..'_.r........ 0000c70: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000c80: 1c00 0000 c80e c097 c80e c097 accd 3948 ..............9H 0000c90: 9bea e850 d0a4 fcb4 0000 0000 0000 02ea ...P............ 0000ca0: 0706 4000 0000 0000 1f00 0000 0000 0000 ..@............. 0000cb0: 7365 6c69 6e75 7800 0000 0000 0000 0000 selinux......... 0000cc0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000cd0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000ce0: 7379 7374 656d 5f75 3a6f 626a 6563 745f system_u:object_ 0000cf0: 723a 7661 725f 6c6f 675f 743a 7330 0000 r:var_log_t:s0..
|
经过一段时间的练习,同学们应该不需要对照表来识辨这些16进制码的含义了,如果不熟练的话,可以回过头多看几遍。我们看到这个inode较之前有了变化。extent的区段数变成了1,区段树的深度变成了1。区段树深度为1,这说明非叶子节点。
|
偏移 |
大小 |
名称 |
描述 |
|
0x0 |
0x0000 0000 |
ei_block |
逻辑块号. |
|
0x4 |
0x001c 037c |
ei_leaf_lo |
区段树中下一层的区段节点块地址(低32位),可以指向叶子节点或者内部节点。 |
|
0x8 |
0x0000 |
ei_leaf_hi |
上一栏的高16位地址 |
|
0xA |
0x000b |
ei_unused |
未使用 |
使用blkcat查看文件系统块1835900的内容,
|
0000000: 0af3 0e00 5401 0000 0000 0000 0000 0000 ....T........... 0000010: 0100 0000 58c2 0b00 0100 0000 0100 0000 ....X........... 0000020: e599 1b00 0200 0000 0100 0000 41e6 2f00 ............A./. 0000030: 0300 0000 0100 0000 b878 1c00 0400 0000 .........x...... 0000040: 0100 0000 2d8b 1b00 0500 0000 0100 0000 ....-........... 0000050: 9a79 1c00 0600 0000 0100 0000 0d82 1b00 .y.............. 0000060: 0700 0000 0100 0000 1182 1b00 0800 0000 ................ 0000070: 0100 0000 1382 1b00 0900 0000 0100 0000 ................ 0000080: 1682 1b00 0a00 0000 0100 0000 1882 1b00 ................ 0000090: 0b00 0000 0300 0000 034e 1c00 0e00 0000 .........N...... 00000a0: 0200 0000 074e 1c00 1000 0000 0400 0000 .....N.......... 00000b0: e082 0c00 0000 0000 0000 0000 0000 0000 ................
|
从上面的数据,我们可以看到有0x000e个区段,也就是在extent header后有14个extent或者extent ixd的结构体。接着看到extent最大数为0x0154=340,这个数字是怎么来的呢?我们知道在一个inode里面,这个值是4,那是因为('extent space' - 'extent header size') / 'extent size' 即 (60-12)/12=4,那么在这里也一样,只不过60这里要变为4096,因为我们不在inode中,而是在一个块中,即4096-12=4084,4084/12即340.333,最后还剩4个字节浪费了。再接着,是树的深度,也就是0x0000表明是叶子节点。那么我们知道,这个文件由着14个block的块组成。有兴趣的同学可以自己把文件dump出来拼一下。呵呵。
本文深入探讨ext4文件系统中的区段树结构,通过实例分析一个名为'messages'的文件,展示了当文件大小超过4个块时,inode信息的变化。随着文件增大,区段数和区段树深度发生变化,解释了extent header、extent数量和最大数的计算方式,揭示了文件由多个block组成的逻辑。对于理解ext4文件系统的内部工作原理具有指导意义。
881

被折叠的 条评论
为什么被折叠?



