基本的には今まで通りExt4_Disk_Layoutを見つつ。
エクステントが有効化かどうかはスーパーブロックのs_feature_incompatのbit0x40(INCOMPAT_EXTENTS)が立っているかどうかでわかる。他にもinodeのi_flagsのビット0x80000(EXT4_EXTENTS_FL)が立っていたらこのinodeはエクステントが使われているとわかる。
エクステントの構造は大きく分けて以下の3個になっている。
- エクステントヘッダー
- エクステントインデックス
- エクステント
エクステントに関するデータ構造はfs/ext4/ext4.hにある。 エクステントヘッダーはstruct ext4_extent_headerで以下のような内容。
94 /* 95 * Each block (leaves and indexes), even inode-stored has header. 96 */ 97 struct ext4_extent_header { 98 __le16 eh_magic; /* probably will support different formats */ 99 __le16 eh_entries; /* number of valid entries */ 100 __le16 eh_max; /* capacity of store in entries */ 101 __le16 eh_depth; /* has tree real underlying blocks? */ 102 __le32 eh_generation; /* generation of the tree */ 103 };
eh_magicはエクステントヘッダーを示すマジックナンバーで0xf30a。eh_depthはエクステントのツリー構造の深さなんだけど、これが0の場合はエクステントインデックスを使わずに直接エクステントを見るようになっている。
エクステントインデックスはstruct ext4_extent_idx で以下のような内容。
82 /* 83 * This is index on-disk structure. 84 * It's used at all the levels except the bottom. 85 */ 86 struct ext4_extent_idx { 87 __le32 ei_block; /* index covers logical blocks from 'block' */ 88 __le32 ei_leaf_lo; /* pointer to the physical block of the next * 89 * level. leaf or next index could be there */ 90 __le16 ei_leaf_hi; /* high 16 bits of physical block */ 91 __u16 ei_unused; 92 };
エクステントext4_extentは以下の通り。
71 /* 72 * This is the extent on-disk structure. 73 * It's used at the bottom of the tree. 74 */ 75 struct ext4_extent { 76 __le32 ee_block; /* first logical block extent covers */ 77 __le16 ee_len; /* number of blocks covered by extent */ 78 __le16 ee_start_hi; /* high 16 bits of physical block */ 79 __le32 ee_start_lo; /* low 32 bits of physical block */ 80 };
実際のデータへのポインタになるのはこのext4_extent。
あとはstruct ext4_extent_tailというエクステントの最後に置かれるデータもあるけど。
60 /* 61 * This is the extent tail on-disk structure. 62 * All other extent structures are 12 bytes long. It turns out that 63 * block_size % 12 >= 4 for at least all powers of 2 greater than 512, which 64 * covers all valid ext4 block sizes. Therefore, this tail structure can be 65 * crammed into the end of the block without having to rebalance the tree. 66 */ 67 struct ext4_extent_tail { 68 __le32 et_checksum; /* crc32c(uuid+inum+extent_block) */ 69 };
では実際のディスクイメージと合わせてみてみる。 まず、エクステントヘッダーがどこにあるのかというところだけど、これはinodeのi_blockの領域が使われている。ここはext3や、ext4でもエクステントを使わない場合はdirect/indirectブロックに使われるところ。 前回も使ったtest.txtのinodeはこのような感じで、この中にi_blockがあるのでそこだけ抜き出すと
00061b00 a4 81 00 00 90 00 00 00 35 fe e4 52 35 fe e4 52 |........5..R5..R| 00061b10 35 fe e4 52 00 00 00 00 00 00 01 00 08 00 00 00 |5..R............| 00061b20 00 00 08 00 01 00 00 00 0a f3 01 00 04 00 00 00 |................| 00061b30 00 00 00 00 00 00 00 00 01 00 00 00 41 80 00 00 |............A...| 00061b40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
このような感じに。
00000000 0a f3 01 00 04 00 00 00 00 00 00 00 00 00 00 00 | ................ 00000010 01 00 00 00 41 80 00 00 00 00 00 00 00 00 00 00 | ....A........... 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 00000030 00 00 00 00 00 00 00 00 00 00 00 00 | ............
先頭の2バイトがマジックナンバーでここはリトルエンディアンなのでひっくり返すと0xf30aに。次はeh_entriesで2バイトなのでエントリ数は1。次は2バイトのeh_maxで最大で4個のエントリが持てると。その次はeh_depthでこれも2バイトで値は0。次も2バイトでeh_generation。これはwikiページによると「Used by Lustre, but not standard ext4」となっているのでext4では未使用。 このファイルはeh_depthが0なのでエクステントインデックスは使われずに直接エクステントにアクセスできることがわかる。
それでは引き続きデータを見ていく。ここからはエクステントで最初が4バイトのee_blockで値は0。次が2バイトのee_lenで値は1。次とその次はブロックのアドレスの上位、下位ビット。最初が上位16bitで0、次が下位32bitで0x8041。 ということで、データが置かれているのはブロック0x8041ということがわかり、これにブロックサイズかけてバイト位置を出すと
masami@saga:~/codes/read_ext4$ echo "obase=16;ibase=16; 8041*1000" | bc 8041000
アドレスは0x8041000ということがわかる。長さ(ee_len)は1なので1ブロック分がこのtest.txtのデータ領域。ではディスクイメージのダンプでそのアドレスを見てみる。
08041000 61 62 63 64 65 66 67 68 0a 61 62 63 64 65 66 67 |abcdefgh.abcdefg| <-- data of test.txt 08041010 68 0a 61 62 63 64 65 66 67 68 0a 61 62 63 64 65 |h.abcdefgh.abcde| 08041020 66 67 68 0a 61 62 63 64 65 66 67 68 0a 61 62 63 |fgh.abcdefgh.abc| 08041030 64 65 66 67 68 0a 61 62 63 64 65 66 67 68 0a 61 |defgh.abcdefgh.a| 08041040 62 63 64 65 66 67 68 0a 61 62 63 64 65 66 67 68 |bcdefgh.abcdefgh| 08041050 0a 61 62 63 64 65 66 67 68 0a 61 62 63 64 65 66 |.abcdefgh.abcdef| 08041060 67 68 0a 61 62 63 64 65 66 67 68 0a 61 62 63 64 |gh.abcdefgh.abcd| 08041070 65 66 67 68 0a 61 62 63 64 65 66 67 68 0a 61 62 |efgh.abcdefgh.ab| 08041080 63 64 65 66 67 68 0a 61 62 63 64 65 66 67 68 0a |cdefgh.abcdefgh.| 08041090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| *
( ´∀`)bグッ!
Linuxカーネル Hacks ―パフォーマンス改善、開発効率向上、省電力化のためのテクニック
- 作者: 池田宗広,大岩尚宏,島本裕志,竹部晶雄,平松雅巳,高橋浩和
- 出版社/メーカー: オライリージャパン
- 発売日: 2011/07/26
- メディア: 単行本(ソフトカバー)
- 購入: 4人 クリック: 50回
- この商品を含むブログ (4件) を見る