未来のいつか/hyoshiokの日記

hyoshiokの日々思うことをあれやこれや

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とデータブロックそしてディレクトリの関連がもう少しで見えて来るはずだ。