Ext2 FS
1. 概要
今となっては、だいぶ古くなったext2 ファイルシステムのメモ。ext3の原型でもある。
2. ディスク上のレイアウト
Ext2ファイルシステムのパーティション内の構造を図1に示す。パーティションは複数のブロックグループに分割される。各ブロックグループには表1に示す領域がある。ブロックグループに分割しているのは、ファイルのフラグメントを減らすため。
領域 |
説明 |
---|---|
スーパーブロック |
パーティション全体に関する情報を持つ。 ・i-node数 ・ブロック数 ・空きブロック数 ・空きi-node数 など。 通常はブロックグループ0のスーパーブロックがプライマリとして使用される。他のブロックグループにあるスーパーブロックはバックアップとして使用される。ただし、全ブロックにバックアップがあるわけではない。 (Ref. to man dumpe2fs, man e2fsck, ext2_fs.h::struct ext2_super_block) |
ブロックディスクリプタ(群) |
ブロックグループ内に関する情報を持つ。 ・ブロックビットマップ領域のブロック番号 ・ i-nodeビットマップ領域のブロック番号 ・i-nodeテーブル領域のブロック番号 ・空きブロック数 ・空きi-node数 など。 自分のブロックグループに対するディスクリプタだけでなく。パーティション内の全ブロックグループのブロックディスクリプタが並べて置かれている。スーパーブロックと同じく使用されるのはブロックグループ0のディスクリプタ。他のブロックグループのディスクリプタはバックアップとして使用される。 (Ref. to ext2_fs.h::struct ext2_group_desc) |
ブロックビットマップ |
データブロック領域のディスクブロックの使用/未使用を管理するビットマップ |
i-nodeビットマップ |
i-nodeテーブル中のi-nodeの使用/未使用を管理するビットマップ |
i-nodeテーブル |
ファイル、ディレクトリを管理するi-nodeが並べられている。 (Ref. to ext2_fs.h::struct ext2_inode) |
データブロック |
ファイル、ディレクトリ等のデータが格納される領域 |
3. i-node
ファイルやディレクトリはi-nodeで管理される。ファイルやディレクトリにはi-nodeテーブルからi-nodeが1つ割り当てられる。i-nodeには、ファイルのパーミッション、オーナー、サイズ、修正日付などの属性情報が格納されている(ext2_fs.h::struct ext2_inode参照)。なお、ファイル名についてはディレクトリエントリで管理される。ディレクトリエントリについては後述。
ファイルやディレクトリの中身のデータについては、i-node内にあるブロック番号を格納したテーブル(ext2_inode.i_block[])によりデータを格納したブロックと関連付けられる(図2)。このテーブルの詳細については「ファイルデータの管理」を参照。
4. ファイルデータの管理
ファイルのデータはデータブロック領域に置かれるが、データブロック領域のどのブロックに格納されているのかは、i-node中のテーブル(ext2_inode.i_block[])で管理される。このテーブルはファイルデータが格納されているディスクブロックのブロック番号を格納しており、ここを参照することでファイルデータにアクセスすることができる。テーブルの最初のエントリがファイルの先頭ブロックのブロック番号、二番目のエントリがファイル中2番目のブロックのブロック番号となっている(図3)。
ブロック番号を格納したテーブルは15エントリある。エントリ0〜11はそのままブロック0〜11のブロック番号を直接指している。エントリ12〜14は扱いが異なり、ブロック番号を間接的に参照するためのテーブルを指している(*1)。これらの間接参照用テーブルにはi-nodeにあるのと同じようにブロック番号を保持したエントリが並んでいる(*2)。間接参照用テーブルから、さらにブロック番号をたどってファイルのデータブロックを指すようになっている。i-node上のテーブルのエントリ12は2段間接参照、 エントリ13は3段間接参照、エントリ14は4段間接参照するようになっている。
ファイル中の14番目(#13)のブロックのデータが格納されているブロックのブロック番号を取得したい場合は、- i-nodeのテーブルのエントリ12から2段目のテーブルを取得
- 2段目のテーブルのエントリ1から#13のブロック番号を取得
というようにテーブルをたどって行くことになる。
このように、ファイルサイズに合わせてブロック管理テーブルを増設して、たどるようにすることで、管理領域の無駄が発生しないようになっている。
(*2) エントリは1ブロックに格納できる分だけ詰め込まれている。1エントリは4byte。
5. ディレクトリエントリ
ディレクトリのi-nodeのデータ(ext2_inode.i_block[]の参照先)は、ディレクトリエントリのリストになっている(図3)。ディレクトリエントリとはファイル/ディレクトリの名前を格納しているエントリのことで、このリストには、ディレクトリ直下にある(ls -aで見える)ファイル/ディレクトリのディレクトリエントリが並んでいる。
ディレクトリエントリのリストから、ディレクトリ内のファイル/ディレクトリの名前一覧を取得できる。また、各ディレクトリエントリは対応するi-nodeの番号を保持しているため、そこから修正時刻などファイルの属性情報やファイル本体を取り出すことができる。
ディレクトリのi-nodeのデータは、そのディレクトリのエントリリストになるので、ディレクトリエントリ=>i-node=>ディレクトリエントリ=> ... のようにしてファイルシステムのツリーをたどれる。