深入理解ext4(二)-- 区段树 ( extent tree )

来源:互联网 发布:2016nba全明星赛数据 编辑:程序博客网 时间:2024/05/29 14:01

 

还记得在上一章中,我们提到过的结构体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 00000af30400 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

暂不讨论

 

因为这里看到depth0,说明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个块。这时候我们看看messagesinode信息,方法不重复了。

 

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后有14extent或者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/12340.333,最后还剩4个字节浪费了。再接着,是树的深度,也就是0x0000表明是叶子节点。那么我们知道,这个文件由着14block的块组成。有兴趣的同学可以自己把文件dump出来拼一下。呵呵。

 

 

 

原创粉丝点击