この節では、UFS ファイルシステムの構成要素、 つまりスーパーブロック、シリンダグループブロック、i ノード、間接ブロック、データブロックに fsck コマンドが適用する整合性検査の種類について説明します。
UFS ファイルシステム構造については、「UFS ファイルシステムのシリンダグループの構造」を参照してください。
スーパーブロックには集計情報が格納されており、UFS ファイルシステム内でもっとも破損しがちな構成要素です。ファイルシステムの i ノードやデータブロックが変更されるたびに、スーパーブロックも変更されます。CPU が停止した場合、直前のコマンドが sync コマンドでなければ、スーパーブロックはほぼ確実に破損しています。
スーパーブロックの不整合は、次の面から検査されます。
ファイルシステムのサイズ
i ノード数
空きブロック数
空き i ノード数
ファイルシステムのサイズは、スーパーブロックと i ノードリストに使用されるブロック数よりも大きくなければなりません。i ノード数は、ファイルシステムの最大許容数よりも小さくなければなりません。i ノードは、ファイルに関するすべての情報を表します。ファイルシステムのサイズとレイアウト情報は、fsck コマンドにとってもっとも重要な情報部分です。これらのサイズはファイルシステムの作成時に静的に決められるため、実際に検査する方法はありません。ただし、fsck コマンドを使用してサイズが妥当な範囲内にあるかどうかは検査できます。ファイルシステムのほかのすべての検査を行うには、これらのサイズが正確でなければなりません。fsck コマンドが一次スーパーブロックの静的パラメータ内に不正な情報を検出すると、オペレータに代替スーパーブロックの位置を指定するように促します。
UFS ファイルシステム構造の詳細は、「UFS ファイルシステムのシリンダグループの構造」を参照してください。
空きブロック数は、シリンダグループのブロックマップに格納されます。fsck コマンドは、空きマーク付きのすべてのブロックがファイルによって使用されていないかどうかを検査します。すべてのブロックを検査し終わると、fsck コマンドは空きブロック数と i ノードによって使用されるブロック数の合計がファイルシステム内の合計ブロック数に等しくなるかどうかを検査します。ブロックマップ内に間違いがあると、fsck コマンドはブロックが割り当てられている状態のままで構築し直します。
スーパーブロック内の集計情報には、ファイルシステム内の空きブロックの合計数のカウントが入っています。fsck コマンドは、このブロック数をファイルシステム内で見つかった空きブロック数と比較します。数が一致しなければ、fsck コマンドはスーパーブロック内の空きブロック数を実際の空きブロック数で置き換えます。
スーパーブロック内の集計情報には、ファイルシステム内の空き i ノード数が入っています。fsck コマンドは、この i ノード数をファイルシステム内で見つかった空き i ノード数と比較します。数が一致しなければ、fsck はスーパーブロック内の空き i ノード数を実際の空き i ノード数で置き換えます。
i ノードリストは、i ノード 2 から順番に検査されます。(i ノード 0 と i ノード 1 は予約ノード)。各 i ノードの不整合は、次の面から検査されます。
形式とタイプ
リンク数
重複ブロック
不正なブロック番号
i ノードのサイズ
各 i ノードには、そのタイプと状態を記述するモードのワードが入っています。i ノードには、次の 9 つのタイプがあります。
割り当て済み
未割り当て
部分的に割り当て済み
ファイルシステムの作成時、決まった数の i ノードは無効になっています。これらは、必要なときが来るまで割り当てられません。「割り当て済みの i ノード」とは、ファイルを指す i ノードです。「未割り当ての i ノード」は、ファイルを指さないので空のはずです。「部分的に割り当て済み」の状態は、i ノードが正しくフォーマットされていないことを意味します。たとえば、ハードウェア障害が原因で i ノードリストに不正なデータが書き込まれると、i ノードは「部分的に割り当て済み」の状態になることがあります。fsck コマンドが実行できる唯一の修正動作は、その i ノードを消去することです。
各 i ノードには、そこにリンクされているディレクトリエントリ数が入っています。fsck コマンドは、ルート (/) ディレクトリから順番にディレクトリ構造全体を検査し、i ノードごとに実際のリンク数を計算して、各 i ノードのリンク数を検証します。
i ノードに格納されているリンク数が fsck コマンドによって判断された実際のリンク数と一致しない場合は、次の 3 つの状況が考えられます。
格納されたリンク数が 0 でなく、実際のリンク数が 0 の場合。
この状況は、i ノードにリンクされているディレクトリエントリが存在しない場合に発生することがあります。この場合、fsck コマンドはリンクされていないファイルを lost+found ディレクトリに入れます。
格納されたリンク数が 0 でなく、実際のリンク数も 0 でない。しかし、それらの数が等しくない場合。
この状況は、ディレクトリエントリが追加または削除されたが、i ノードが更新されていない場合に発生することがあります。この場合、fsck コマンドは格納されたリンク数を実際のリンク数で置き換えます。
格納されたリンク数が 0 で実際のリンク数が 0 でない場合。
この場合、fsck コマンドは i ノードのリンク数を実際のリンク数に変更します。
各 i ノードには、それが使用するすべてのブロックのリスト、またはリストを指すポインタ (間接ブロック) が入っています。間接ブロックは i ノードによって所有されるので、間接ブロックの整合性が失われると、それを所有する i ノードが直接影響を受けます。
fsck コマンドは、i ノードから使用される各ブロック番号を、割り当て済みブロックのリストと比較します。別の i ノードからすでにブロック番号が使用されていると、そのブロック番号は重複ブロックのリストに入れられます。それ以外の場合は、割り当て済みブロックのリストが更新され、ブロック番号が追加されます。
重複ブロックが見つかると、fsck コマンドは再び i ノードリストを調べて、各重複ブロックを使用するほかの i ノードを検索します。fsck コマンドでは、どの i ノードでエラーが発生しているか、正確に判断することはできません。このため、保持する i ノードと消去する i ノードを選択するように促すプロンプトが表示されます。i ノード内に多数の重複ブロックが入っている場合は、ファイルシステムに書き込まれていない間接ブロックの影響を受けている可能性があります。
fsck コマンドは、i ノードから使用される各ブロック番号を検査して、その値がファイルシステム内の最初のデータブロック番号の値よりも大きく、最後のデータブロック番号の値より小さいかどうかを調べます。ブロック番号がこの範囲に含まれない場合は、不正なブロック番号と見なされます。
間接ブロックがファイルシステムに正しく書き込まれていないことが原因で、i ノード内に不正なブロック番号が発見されることがあります。fsck コマンドはその i ノードの消去を促すプロンプトを表示します。
各 i ノードには、参照するデータブロック数が入っています。実際のデータブロック数は、割り当て済みのデータブロック数と間接ブロック数の合計です。fsck コマンドはデータブロック数を計算し、そのブロック数を i ノードから使用されるブロック数と比較します。i ノードに不正なブロック数が入っていると、fsck コマンドはその修正を促すプロンプトを表示します。
各 i ノードには、64 ビットのサイズフィールドがあります。このフィールドは、i ノードに関連付けられたファイル内の文字数 (データバイト数) を示します。i ノードのサイズフィールドに整合性があるかどうかは、サイズフィールド内の文字数を使用して、i ノードに関連付けるべきブロック数を計算し、その結果を i ノードから使用される実際のブロック数と比較して概算で検査されます。
間接ブロックは i ノードによって所有されます。したがって、間接ブロック内の整合性が失われると、それを所有する i ノードが影響を受けます。不整合は、次の面から検査されます。
すでに別の i ノードから使用されているブロック
ファイルシステムの範囲に含まれないブロック番号
直接ブロックに対しても整合性検査が実行されます。
i ノードは、3 種類のデータブロックを直接または間接に参照できます。参照されるブロックは、すべて同じ種類でなければなりません。次の 3 種類のデータブロックがあります。
プレーンデータブロック
シンボリックリンクデータブロック
ディレクトリデータブロック
プレーンデータブロックには、ファイルに格納される情報が入っています。シンボリックリンクデータブロックには、シンボリックリンクに格納されるパス名が入っています。ディレクトリデータブロックには、ディレクトリエントリが入っています。fsck コマンドはディレクトリデータブロックの妥当性しか検査できません。
ディレクトリは、i ノードの mode フィールド内のエントリによって通常ファイルと区別されます。ディレクトリに関連付けられたデータブロックには、ディレクトリエントリが入っています。ディレクトリデータブロックの不整合は、次の面から検査されます。
未割り当ての i ノードを指すディレクトリ内の i ノード番号
ファイルシステム内の i ノード番号より大きいディレクトリ内の i ノード番号
「.」と「..」ディレクトリには許されないディレクトリ内の i ノード番号
ファイルシステムから切り離されたディレクトリ
ディレクトリデータブロック内の i ノード番号が未割り当て i ノードを指す場合、fsck コマンドはそのディレクトリエントリを削除します。この状況は、新しいディレクトリエントリが入っているデータブロックが変更されて書き出されたが、i ノードが書き込まれていない場合に発生します。また、警告なしに CPU が停止された場合にも発生します。
ディレクトリエントリの i ノード番号が i ノードリストの最後を超える位置を指す場 合、fsck コマンドはそのディレクトリエントリを削除します。この状況は、不正なデータがディレクトリのデータブロックに書き込まれると発生します。
「.」ディレクトリの i ノード番号のエントリは、ディレクトリデータブロックの最初のエントリでなければなりません。また、それ自体を参照しなければなりません。つまり、その値はディレクトリデータブロックの i ノード番号に等しくなければなりません。
「..」ディレクトリの i ノード番号は、ディレクトリデータブロックの第 2 のエントリでなければなりません。その値は、親ディレクトリの i ノード番号 (または、ディレクトリがルート (/) ディレクトリの場合は、それ自体の i ノード番号) に等しくなければなりません。
「.」と「..」ディレクトリの i ノード番号が不正であれば、fsck コマンドはそれらを正しい値で置き換えます。ディレクトリへのハードリンクが複数個ある場合は、最初に見つかったハードリンクが「..」が指す実際の親であると見なされます。この場合、fsck コマンドはほかの名前を削除するように促すプロンプトを表示します。
fsck コマンドは、ファイルシステム全体で参照関係を検査します。ファイルシステムにリンクされていないディレクトリが見つかると、fsck コマンドはそのディレクトリをファイルシステムの lost+found ディレクトリにリンクします。この条件は、ファイルシステムに i ノードは書き込まれたが、対応するディレクトリデータブロックは書き込まれていない場合に発生する可能性があります。
通常ファイルに関連付けられたデータブロックには、ファイルの内容が入っています。fsck コマンドは、通常ファイルのデータブロックの内容が有効かどうかは検査しません。