ext2の解剖
問題を簡単にするためにフロッピーディスクでext2がどのように配置されているか確認してみる。mke2fsでファイルシステムを作成し、hyoshiokというディレクトリを作り、試しにtestというファイルを作った。
# ls -ail /mnt/floppy/
total 18
2 drwxr-xr-x 4 root root 1024 Aug 12 23:54 .
832321 drwxr-xr-x 4 root root 4096 Apr 30 09:22 ..
12 drwxr-xr-x 2 root root 1024 Aug 12 23:55 hyoshiok
11 drwx------ 2 root root 12288 Aug 12 23:50 lost+found
# cd hyoshiok
# ls -ail
total 3
12 drwxr-xr-x 2 root root 1024 Aug 12 23:55 .
2 drwxr-xr-x 4 root root 1024 Aug 12 23:54 ..
14 -rw-r--r-- 1 root root 10 Aug 12 23:55 testここでhyoshiokディレクトリのi-node番号が12(一番左端の数字)でtestというファイルのi-node番号が14だということがわかる。
Figure 1-1. floppy disk meta-data layout
offset # of blocks description
-------- ----------- -----------
0 1 boot record
-- block group 0 --
(1024 bytes) 1 superblock
2 1 group descriptors
3 1 block bitmap
4 1 inode bitmap
5 23 inode table
28 1412 data blocksダンプをとって確認してみる。
# od -t xz -Ad /dev/fd0 0000000 00000000 00000000 00000000 00000000 >................< * 0001024 000000b8 000005a0 00000048 00000575 >........H...u...< 0001040 000000ab 00000001 00000000 00000000 >................< 0001056 00002000 00002000 000000b8 411b8f70 >. ... ......p..A< 0001072 411b90f6 00170002 0001ef53 00000001 >...A....S.......< 0001088 411b83ba 00ed4e00 00000000 00000001 >...A.N..........< 0001104 00000000 0000000b 00000080 00000000 >................< 0001120 00000002 00000001 c45ce3ba 7e4d1574 >..........\.t.M~< 0001136 aa2aba95 cf326e1c 00000000 00000000 >..*..n2.........< 0001152 00000000 00000000 00000000 00000000 >................< * 0001248 00000000 00000000 00000000 a9738cd1 >..............s.< 0001264 5542dd51 ac836685 364518a3 00000002 >Q.BU.f....E6....< 0001280 00000000 00000000 411b83ba 00000000 >...........A....< 0001296 00000000 00000000 00000000 00000000 >................< *
odコマンドのオプションについては # man od して確認してほしい。*が付いている行は前の行の値と等しくて省略されている。
最初の1024行は00000000 00000000 00000000 00000000が続いている。(全部ゼロ)このブロック(1KB)はブートブロックで通常は使わない。パーティションの先頭ブロックはブートセクターとして予約されている。
次のブロックはスーパーブロックと呼ばれるもので、ファイルシステムの様々な属性情報を持つ。
Figure 1-2. superblock structure
offset size description
------- ------- -----------
0 4 s_inodes_count
4 4 s_blocks_count
8 4 s_r_blocks_count
12 4 s_free_blocks_count
16 4 s_free_inodes_count
20 4 s_first_data_block
24 4 s_log_block_size
28 4 s_log_frag_size
32 4 s_blocks_per_group
36 4 s_frags_per_group
40 4 s_inodes_per_group
44 4 s_mtime
48 4 s_wtime
52 2 s_mnt_count
54 2 s_max_mnt_count
56 2 s_magic
58 2 s_state
60 2 s_errors
62 2 s_minor_rev_level
64 4 s_lastcheck
68 4 s_checkinterval
72 4 s_creator_os
76 4 s_rev_level
80 2 s_def_resuid
82 2 s_def_resgid
-- EXT2_DYNAMIC_REV Specific --
84 4 s_first_ino
88 2 s_inode_size
90 2 s_block_group_nr
92 4 s_feature_compat
96 4 s_feature_incompat
100 4 s_feature_ro_compat
104 16 s_uuid
120 16 s_volume_name
136 64 s_last_mounted
200 4 s_algo_bitmap
-- Performance Hints --
204 1 s_prealloc_blocks
205 1 s_prealloc_dir_blocks
206 2 - (alignment)
-- Journaling Support --
208 16 s_journal_uuid
224 4 s_journal_inum
228 4 s_journal_dev
232 4 s_last_orphan
-- Unused --
236 788 - (padding)先のダンプだとs_inodes_countの値は16進数で0xb8なので10進数で言えば184になる。またs_blocks_countは16進数で0x5a0、10進数で1440ブロックである。1ブロックが1KBなので1440KBということになる。
その次はグループディスクリプタである。
Figure 1-3. group_desc structure
offset size description
------- ------- -----------
0 4 bg_block_bitmap
4 4 bg_inode_bitmap
8 4 bg_inode_table
12 2 bg_free_blocks_count
14 2 bg_free_inodes_count
16 2 bg_used_dirs_count
18 2 bg_pad
20 12 bg_reservedダンプしてみた値は下記のとおり。
0002048 00000003 00000004 00000005 00ab0575 >............u...< 0002064 00000003 00000000 00000000 00000000 >................< 0002080 00000000 00000000 00000000 00000000 >................< *
bg_block_bitmapはブロックビットマップのブロック番号。ここでは3である。bg_inode_bitmapはinodeビットマップのブロック番号。ここでは4。bg_inode_tableは最初のinodeテーブルがあるブロック番号。5である。ビットマップはビットの列でビットの値が0の時対応するinodeないしはデータブロックが空きである事を示す。ビットマップは1ブロックに納める必要がある。通常ブロックサイズは1024、2048、4096バイトのいずれかであるため、一つのビットマップには(1バイトは8ビットなので)8192、16384、32768個のブロックの状態を表すことになる。
データブロックビットマップ、inodeビットマップ、inodeテーブルの始めの方のダンプは以下の通りだ。
0003072 ffffffff 000201ff 00000000 00000000 >................< 0003088 00000000 00000000 00000000 00000000 >................< * 0003248 80000000 ffffffff ffffffff ffffffff >................< 0003264 ffffffff ffffffff ffffffff ffffffff >................< * 0004096 00002fff 00000000 00000000 00000000 >./..............< 0004112 00000000 ff000000 ffffffff ffffffff >................< 0004128 ffffffff ffffffff ffffffff ffffffff >................< * 0005120 00000000 00000000 411b83ba 411b83ba >...........A...A< 0005136 411b83ba 00000000 00000000 00000000 >...A............< 0005152 00000000 00000000 00000000 00000000 >................< * 0005248 000041ed 00000400 411b8fd6 411b849a >.A.........A...A< 0005264 411b849a 00000000 00040000 00000002 >...A............< 0005280 00000000 00000000 0000001c 00000000 >................< 0005296 00000000 00000000 00000000 00000000 >................< *
なかなかファイルまでたどりつけないが少しずつ前進しているはずだ。
inodeとデータブロックそしてディレクトリの関連がもう少しで見えて来るはずだ。