JFS2 ファイル・スペースの割り当て

ファイル・スペースの割り当ては、 オペレーティング・システム内でデータを物理ストレージ・スペースに割り当てる方法です。

カーネルは、ディスク・スペースを論理ブロック の形でファイルまたはディレクトリーに割り当てます。 論理ブロックとは、512、1024、2048、または 4096 バイト単位に分割したファイルまたはディレクトリーの内容を意味します。 JFS2 ファイルシステムを作成する時、512、1024、2048、または 4096 バイトのいずれかの論理ブロック・サイズを指定します。 論理ブロックは実体のあるエンティティーではありませんが、 論理ブロック内のデータはディスク上で物理ストレージ・スペースを使用します。 各ファイルまたはディレクトリーは 0 個以上の論理ブロックからなります。

完全論理ブロックと部分論理ブロック

ファイルまたはディレクトリーには、 完全論理ブロックまたは部分論理ブロックが入っている場合があります。 完全論理ブロックには、JFS2 ファイルシステムの作成時に指定されたファイルシステムのブロック・サイズに従って、 512、1024、2048、または 4096 バイトのデータが入っています。 部分論理ブロックは、ファイルまたはディレクトリーの最後の論理ブロックに、 ファイルシステムのブロック・サイズ未満のデータが入っている場合に発生します。

例えば、論理ブロック・サイズが 4096 である JFS2 ファイルシステムの 8192 バイトのファイルは、 2 つの論理ブロックになります。 最初の 4096 バイトは最初の論理ブロックに存在し、 次の 4096 バイトは 2 番目の論理ブロックに存在します。 同様に、4608 バイトのファイルも 2 つの論理ブロックからなります。 しかし、最後の論理ブロックは、ファイルのデータの最後の 512 バイトの入った部分論理ブロックになります。

JFS2 ファイル・スペースの割り当て

デフォルトのブロック・サイズは 4096 バイトです。 ファイルシステムの作成時に、mkfs コマンドを使用すれば、より小さなブロック・サイズを指定することができます。 指定できるブロック・サイズは、512、1024、2048、および 4096 バイトです。 1 つのファイルシステムで使用できるブロック・サイズは 1 つだけです。

カーネルは、最後のファイルシステム・ブロックのデータだけが部分ブロック割り当てを受け取るように、 ディスク・スペースを割り当てます。 部分ブロックが現在の割り当ての制限を超えて成長した場合、追加のブロックが割り当てられます。

ファイル・ホールを表す論理ブロックにデータが追加された場合も、ブロックの再割り当てが発生します。ファイル・ホール は、 データを最後に保管した論理ブロックの前にある空の論理ブロックです。 (ファイル・ホールは、ディレクトリー内では発生しません。) このような空の論理ブロックに、ブロックは割り当てられていません。 しかし、ファイル・ホールにデータを追加すると、割り当てが発生します。 ディスク・スペースを以前に割り当てられていない各論理ブロックには、 ファイルシステム・ブロックのスペースが割り当てられます。

ファイルまたはディレクトリー内の既存のデータを上書きする場合、追加のブロック割り当ては不要です。 既存のデータが入っている論理ブロックは、 既にファイルシステム・ブロックが割り当てられています。

JFS2 は、ファイルまたはディレクトリーの論理ブロックに対して、 ディスク上で連続した割り当てが維持されるように試みます。 連続した割り当ての維持はシーク時間を削減します。 なぜなら、ファイルまたはディレクトリーのデータが、順次にアクセス可能で、 ディスクの同じ領域で検出できるからです。 連続する割り当てに必要なディスク・スペースは、別のファイルまたはディレクト リーが既にそこに書き込みを行っている場合、使用できないことがあります。

ファイルシステムは、 ブロック割り当てマップ と呼ばれるビットマップを使用して、 ファイルシステム内のすべてのブロックの状況を記録します。 ファイルシステムは、新しいブロックを割り当てる必要がある場合、ブロック割り当てマップを参照して、 使用可能なブロックを識別します。 ブロックを割り当てることができるのは、一度に単一のファイルまたはディレクトリーだけです。

エクステント

エクステントとは、JFS2 オブジェクトに 1 つの単位として割り当てられた、 ファイルシステム・ブロックの連続した可変長のシーケンスです。 ラージ・エクステントは、複数の割り当てグループにまたがる場合があります。

i ノードは、すべての JFS2 オブジェクトを表します。 i ノードには、タイム・スタンプあるいは ファイル・タイプ (通常のファイル・タイプ、またはディレクトリー) などの想定されるオブジェクト固有情報が入っています。 このノードには、エクステントの割り当てを記録するための B+ ツリーも入っています。

エクステントの定義には、長さとアドレスの値が必要です。 長さはファイルシステム・ブロック・サイズの単位で測られます。 24 ビット値がエクステントの長さを表すので、エクステントのサイズの範囲は、 1 から 224 -1 ファイルシステム・ブロックです。 したがって、最大エクステントのサイズは、ファイルシステム・ブロックのサイズによって異なります。 アドレスは、エクステントの最初のブロックのアドレスです。 このアドレスも、ファイルシステム・ブロックのユニット内にあります。つまり、 ファイルシステムの先頭からのブロック相対位置です。

エクステント・ベースのファイルシステムを、 ユーザー指定のファイルシステム・ブロック・サイズと結合することによって、JFS2 では、内部フラグメント化の個別のサポートが不要になります。 小さいファイルシステム・ブロック・サイズ (例えば 512 バイト) を指定してファイルシステムを構成し、小さなサイズの多くのファイルを使用して、ファイルシステムの内部のフラグメント化を最小限にすることができます。

一般に、JFS2 の割り当てポリシーは、各エクステントをできるだけ大きくかつ連続させ、 エクステント数を最小化することによって、連続する割り当ての最大化を試みます。 これによって、より大きな入出力転送が可能になり、パフォーマンスが向上します。 ただし、これが常に可能とは限りません。

B+ ツリー

B+ ツリー・データ構造は、ファイルのレイアウトに使用されます。 JFS2 が実行する最も一般的な操作は、 エクステントの読み取りと書き込みです。 これらの操作のパフォーマンスを向上させるため、B+ ツリーが使用されます。

エクステント割り当てディスクリプター (xad_t 構造体) は、エクステントについて記述し、ファイルを表すために必要な 2 つのフィールドを追加します。 これらのフィールドは、エクステントが表す論理バイト・アドレスを示すオフセット・フィールドとフラグ・フィールドです。 xad_t 構造体は /usr/include/j2/j2_xtree.h ファイルに定義されています。

xad 構造体は以下の 2 つの抽象的な範囲を示します。

  • ディスク・ブロックの物理的範囲。 これは、ファイルシステム・ブロック番号の addressXAD(xadp) アドレスから開始し、lengthXAD(xadp) ファイルシステム・ブロックまで拡張します。
  • ファイル内のバイトの論理的範囲。 これは、バイト番号 offsetXAD(xadp)*(ファイルシステム・ブロック・サイズ) から開始し、lengthXAD(xadp)*(ファイルシステム・ブロック・サイズ) まで拡張します。

物理的範囲と論理的範囲の長さは、共に同じバイト数です。 オフセットは、ファイルシステム・ブロック・サイズの単位で保管されることに注意してください (例えば、オフセットの値が 3 である場合、3 バイトではなく、3 ファイルシステム・ブロックを意味します)。 ファイル内のエクステントは常に、ファイルシステム・ブロック・サイズの境界に位置合わせされます。

JFS2 の制限

JFS2 はファイル拡張時に、少なくとも 4 KB の長さあるいは 1 ページ分の連続フリー・スペースを必要とします。 少なくとも 4 KB の連続フリー・スペースがない場合は、さらに小さなブロック の状態で使用可能な十分なストレージ・スペースがあっても、ファイルシステ ムはファイルを拡張させません。