ext 2ファイルシステム全体のストレージレイアウト



ext 2ファイルシステム全体のストレージレイアウト


1つのディスクは複数のパーティションに分割できることを知っています.各パーティションは、フォーマットツール(たとえば、あるmkfsコマンド)であるフォーマットのファイルシステムにフォーマットしてから、ファイルを格納する必要があります.フォーマットのプロセスでは、ディスクにストレージレイアウトを管理する情報が書かれます.次の図は、ディスクパーティションをext 2ファイルシステムにフォーマットしたストレージレイアウトです.
図29.2.ext 2ファイルシステムの全体的なストレージレイアウト
ファイルシステムに格納される最小単位はブロック(Block)であり、1つのブロックの大きさはフォーマット時に決定され、例えばmke2fs-bオプションはブロックサイズを1024、2048または4096バイトに設定することができる.上の図の起動ブロック(Boot Block)の大きさは決定され、1 KBであり、起動ブロックはPC規格によって規定され、ディスクパーティション情報と起動情報を格納するために使用され、どのファイルシステムも起動ブロックを使用できない.ブロックを起動してからext 2ファイルシステムが開始され、ext 2ファイルシステムはパーティション全体を同じサイズのブロックグループ(Block Group)に分割し、各ブロックグループは以下の部分から構成される.
スーパーブロック
ブロックサイズ、ファイルシステムバージョン番号、前回mountの時刻など、パーティション全体のファイルシステム情報を記述します.スーパーブロックは、各ブロックグループの先頭にコピーされます.
ブロックグループ記述子テーブル(GDT,Group Descriptor Table)
複数のブロックグループ記述子からなり、パーティション全体が複数のブロックグループに分割されると、複数のブロックグループ記述子が対応する.各ブロックグループ記述子(Group Descriptor)は、1つのブロックグループの記述情報を格納する.例えば、このブロックグループにおいて、どこからinodeテーブルが開始され、どこからデータブロックが開始され、空きinodeとデータブロックがどれだけ存在するかなどである.スーパーブロックと同様に、ブロックグループ記述子テーブルには、各ブロックグループの先頭にもコピーがあります.これらの情報は非常に重要です.スーパーブロックが予期せぬ破損をすると、パーティション全体のデータが失われ、ブロックグループ記述子が予期せぬ破損をすると、ブロックグループ全体のデータが失われます.これは、複数のコピーがあるためです.通常、カーネルは0番目のブロックグループのコピーのみに使用され、e2fsckファイルシステムの整合性をチェックすると、0番目のブロックグループのスーパーブロックとブロックグループ記述子テーブルが他のブロックグループにコピーされ、0番目のブロックグループの先頭が予期せぬ破損した場合に他のコピーで復元され、損失が減少します.
ブロックビットマップ
1つのブロックグループのブロックは、あるパーティションのブロックサイズが1024バイト、あるファイルが2049バイトであるなど、すべてのファイルのデータを格納するために、3つのブロックが必要であり、3番目のブロックが1バイトしか保存されていなくても1つのブロック全体を占有する必要がある.スーパーブロック、ブロックグループ記述子テーブル、ブロックビットマップ、inodeビットマップ、inodeテーブルのいくつかの部分は、ブロックグループの記述情報を格納する.では、ファイルデータやその他の記述情報を格納するためにどのブロックが使用されているのか、どのブロックがまだ空いているのかをどのように知るのでしょうか.ブロックビットマップは、ブロックグループ全体のどのブロックがどのブロックで空きを使用しているかを記述するために使用され、それ自体が1つのブロックを占め、各bitは本ブロックグループの1つのブロックを表し、このbitは1でブロックが使用されていることを示し、このbitは0でブロック空きが使用可能であることを示す.
なぜdf命令でディスク全体の空き容量を統計するのが非常に速いのでしょうか?各ブロックグループのブロックビットマップを表示するだけで、パーティション全体を検索する必要はありません.逆に、duコマンドで大きなディレクトリを表示するのは、ディレクトリ全体のすべてのファイルを検索することが避けられないため、非常に遅いです.
これに関連するもう一つの問題は、パーティションをフォーマットするときにどのくらいのブロックグループが描画されるかということです.主な制限は、ブロックビットマップ自体が1つのブロックしか占めていないことである.mke2fsフォーマット時のデフォルトブロックサイズは1024バイトで、-bパラメータでブロックサイズを指定できます.現在、ブロックサイズをbバイトとして指定すると、1つのブロックに8 b個のbitがあり、このようなサイズの1つのブロックビットマップで8 b個のブロックの占有状況を表すことができます.そのため、1つのブロックグループには最大8 b個のブロックがあり、パーティション全体にs個のブロックがあれば、s/(8 b)個のブロックグループがあります.フォーマット時には-gパラメータで1つのブロック群のブロック数を指定できますが、通常は手動で指定する必要はありませんmke2fsツール会計で最適な数値を算出します.
inodeビットマップ
ブロックビットマップと同様に、各bitはinodeが空き使用可能であるかどうかを示すブロック自体が1つのブロックを占めている.
inodeテーブル
1つのファイルには、データの格納に加えて、ファイルタイプ(通常、ディレクトリ、シンボルリンクなど)、権限、ファイルサイズ、作成/変更/アクセス時間など、いくつかの記述情報も格納する必要があることが知られています.つまり、ls -lコマンドで見た情報であり、これらの情報はデータブロックではなくinodeに存在します.各ファイルにはinodeがあり、1つのブロックグループ内のすべてのinodeがinodeテーブルを構成します.
Inodeテーブルがどれだけのブロックを占めるかは、フォーマット時にブロックグループ記述子に決定して書き込むことになります.mke2fsフォーマットツールのデフォルトポリシーは、1つのブロックグループがどれだけ8 KBあるかで、どれだけのinodeが割り当てられます.ブロックがブロック全体の大部分を占めているため、ブロックが何個8 KBあれば何個のinodeを割り当てるかを近似することもできる.言い換えれば、平均ファイルサイズが8 KBであれば、パーティションがいっぱいになるとinodeテーブルが十分に利用され、ブロックも無駄にならない.このパーティションが大きなファイル(例えば映画)で保存されていると、データブロックが切れたときにinodeが浪費され、このパーティションが小さなファイル(例えばソースコード)で保存されていると、データブロックがまだinodeを使い切っていない可能性があり、データブロックが浪費されている可能性があります.ユーザがフォーマット時にこのパーティション以降に格納するファイルサイズを予測できる場合、mke2fs-iパラメータでinodeを何バイトごとに割り当てるかを手動で指定することもできます.
データブロック(Data Block)
ファイルの種類によっては次のような場合があります.
  • 通常ファイルの場合、ファイルのデータはデータブロックに格納される.
  • ディレクトリについては、そのディレクトリの下にあるすべてのファイル名とディレクトリ名がデータブロックに格納されており、ファイル名がそのディレクトリにあるデータブロックにファイル名が格納されていることに注意し、ファイル名以外はls -lコマンドで見たその他の情報がそのファイルのinodeに保存されている.この概念に注意してください.ディレクトリもファイルであり、特殊なタイプのファイルです.
  • シンボルリンクの場合、ターゲットパス名が短い場合はinodeに直接保存して検索を高速化し、ターゲットパス名が長い場合はデータブロックを割り当てて保存する.
  • デバイスファイル、FIFO、socketなどの特殊ファイルにはデータブロックがなく、デバイスファイルのプライマリ・デバイス番号とセカンダリ・デバイス番号はinodeに保存されている.

  • これらの概念を理解するためにいくつかの小さな実験をします.例えばhomeディレクトリ下ls -l:
    $ ls -l
    total 32
    drwxr-xr-x 114 akaedu akaedu 12288 2008-10-25 11:33 akaedu
    drwxr-xr-x 114 ftp    ftp     4096 2008-10-25 10:30 ftp
    drwx------   2 root   root   16384 2008-07-04 05:58 lost+found

    なぜ各ディレクトリのサイズは4096の整数倍なのですか?このパーティションのブロックサイズは4096なので、ディレクトリのサイズは常にデータブロックの整数倍です.どうしてディレクトリが大きいものと小さいものがありますか.ディレクトリのデータ・ブロックには、その下のすべてのファイルとディレクトリの名前が保存されているため、1つのディレクトリにファイルが多く、1つのブロックにこんなに多くのファイル名が入れられない場合、より多くのデータ・ブロックがこのディレクトリに割り当てられる可能性があります.たとえば、
    $ ls -l /dev
    ...
    prw-r-----  1 syslog adm            0 2008-10-25 11:39 xconsole
    crw-rw-rw-  1 root   root      1,   5 2008-10-24 16:44 zero
    xconsoleファイルのタイプはp(pipeを示す)FIFOファイルであり、後述するカーネルバッファの識別子であり、ディスクにデータを保存しないため、データブロックがなく、ファイルサイズは0である.zeroファイルのタイプはc文字デバイスファイルを表し、カーネル内のデバイスドライバの1つを表し、データブロックもなく、元々ファイルサイズを書くべき場所に1, 5この2つの数字が書かれていて、プライマリ・デバイス番号とセカンダリ・デバイス番号を表しています.このファイルを尋ねると、カーネルはデバイス番号に応じて対応するドライバを見つけます.たとえば、
    $ touch hello
    $ ln -s ./hello halo
    $ ls -l
    total 0
    lrwxrwxrwx 1 akaedu akaedu 7 2008-10-25 15:04 halo -> ./hello
    -rw-r--r-- 1 akaedu akaedu 0 2008-10-25 15:04 hello

    ファイルhello作成されたばかりでバイト数が0、シンボルリンクファイルhalo指向helloバイト数が7なのはなぜですか?実は7は「./hello」という7文字で、シンボルリンクファイルにはこのようなパス名が保存されています.ハードリンクをもう一度試してみます.
    $ ln ./hello hello2
    $ ls -l
    total 0
    lrwxrwxrwx 1 akaedu akaedu 7 2008-10-25 15:04 halo -> ./hello
    -rw-r--r-- 2 akaedu akaedu 0 2008-10-25 15:04 hello
    -rw-r--r-- 2 akaedu akaedu 0 2008-10-25 15:04 hello2
    hello2helloファイル名の違いを除いては、他の属性がそっくりであり、またhelloの属性が変化し、2番目の欄の数字は元々1であったが、現在は2となっている.根本的には、hello・とhello2は同じファイルがファイルシステムにある2つの名前であるls -l2番目の欄の数字はハードリンク数であり、1つのファイルがファイルシステムにいくつかの名前があることを示し(これらの名前は異なるディレクトリのデータブロックに保存できるか、あるいは異なるパスの下に位置することができる)、ハードリンク数もinodeに保存される.同じファイルである以上、inodeはもちろん1つしかないので、ls -lそれらの属性はそっくりです.このinodeから読んだものですから.ディレクトリのハードリンク数を検討します.
    $ mkdir a
    $ mkdir a/b
    $ ls -ld a
    drwxr-xr-x 3 akaedu akaedu 4096 2008-10-25 16:15 a
    $ ls -la a
    total 20
    drwxr-xr-x   3 akaedu akaedu  4096 2008-10-25 16:15 .
    drwxr-xr-x 115 akaedu akaedu 12288 2008-10-25 16:14 ..
    drwxr-xr-x   2 akaedu akaedu  4096 2008-10-25 16:15 b
    $ ls -la a/b
    total 8
    drwxr-xr-x 2 akaedu akaedu 4096 2008-10-25 16:15 .
    drwxr-xr-x 3 akaedu akaedu 4096 2008-10-25 16:15 ..

    まずディレクトリaを作成し、その下にサブディレクトリa/bを作成します.ディレクトリaのハードリンク数は3で、この3つの名前はそれぞれ現在のディレクトリの下aaディレクトリの下.およびbディレクトリの下..です.ディレクトリbのハードリンク数は2で、それぞれaディレクトリ下bおよびbディレクトリ下.です.なお、ディレクトリのハードリンクはこのようにしか作成できません.lnコマンドではディレクトリのシンボルリンクを作成できますが、ディレクトリのハードリンクは作成できません.