Unix File System (UFS) の詳細解説
Unix File System (UFS) は、
Unix系オペレーティングシステム(OS)で広く使用される
ファイルシステムです。これは単一の
ファイルシステムを指すのではなく、
Version 7 Unixの
ファイルシステムから派生した一連の
ファイルシステムの総称です。
特に、4.2BSDで導入されたFast File System (FFS) がUFSとして一般的に知られており、その他にもFFFS、UFS2、UFS Loggingなど、さまざまな派生形が存在します。
UFSの設計
UFSボリュームは、以下のような要素で構成されています。
1.
ブートブロック: パーティションの先頭に位置し、システム起動時に必要なコードが格納される領域です。
2.
スーパーブロック: ファイルシステム全体の情報を持つ重要な領域です。マジックナンバー、構成情報、統計データ、チューニングパラメータなどが含まれます。
3.
シリンダグループ: ディスクを分割した単位で、複数のシリンダグループから構成されます。各シリンダグループには以下の要素が含まれます。
スーパーブロックのバックアップコピー
シリンダグループヘッダ: 統計情報やフリーリストなどの情報を持つ。
inode群: ファイルの属性情報を格納するデータ構造。
データブロック群: ファイルの実データを格納する領域。
inode は、ファイルごとに割り当てられる識別子で、
ファイルシステム内で一意の番号が振られています。
ディレクトリファイルは、その
ディレクトリ内のファイル名と対応するinode番号のみを保持しており、ファイルの
メタデータはinodeに格納されています。
UFSの背景
初期のUNIXでは、
ファイルシステムは単純にFSと呼ばれていました。FSは
ブートブロック、スーパーブロック、inode群、データブロック群のみで構成されており、当時の小容量ディスクではこれで十分でした。しかし、ディスク容量の増大に伴い、inodeとデータブロック間のヘッド移動による効率低下が無視できなくなりました。
この問題を解決するために、BSDで導入されたのがFFSです。FFSではディスクをシリンダグループに分割し、各グループにinodeとデータブロックを配置することで、アクセスを局所化しました。
FFSは、データブロックとそれに関連する
メタデータを同じシリンダグループに配置することで、
ディレクトリのコンテンツがディスク全体に分散するのを防ぎ、
フラグメンテーションを低減します。
また、スーパーブロックには、トラック数、セクタ数、回転速度などのディスク性能に関するパラメータも含まれており、システムはこれを最適化に利用します。
ディスク容量が増加するにつれて、セクタレベルの最適化は効果が薄れてきました。特にファイルが巨大化すると、読み込みが断片化する問題が顕著になりました。これに対して、BSDはブロックサイズを1セクタから1K、そしてFFSでは8Kに増やすことで、ファイルの連続的な格納を促進し、オーバーヘッドを削減しました。
しかし、ブロックサイズを大きくすると、小さいファイルが多い場合には領域の無駄が発生します。この問題を解決するために、BSDではブロックレベルのフラグメント化を導入しました。ファイルの最後の部分をブロックサイズのサブブロックに格納することで、領域の利用効率を高めました。
UFSの実装
SunOS/
Solaris、SVR4、HP-UX、Tru64 UNIXなどの商用UNIXシステムでは、UFSが採用されています。多くの場合、各ベンダーが独自の拡張を施しているため、異なるベンダーのUFS間での互換性は低い傾向にあります。ただし、基本的なブロックサイズやデータフィールド幅は保持されていることが多く、ある程度の互換性は保たれています。
サン・マイクロシステムズは
Solaris 7で、ジャーナリング機能を追加したUFS Loggingを導入しました。
Solaris UFSには、巨大ファイルやディスクを扱うための拡張機能も追加されています。
カーク・マキュージックはFreeBSDのFFS層とUFS層を拡張し、UFS2を開発しました。UFS2は
64ビットのブロックポインタを使用し、最大8
ゼタバイトまでのボリュームをサポートし、ブロックサイズの可変化やフラグフィールドの拡張、birthtimeタイムスタンプの追加などの機能拡張を行いました。FreeBSD 5.0以降ではUFS2がデフォルトとなっています。
FreeBSDでは、ソフトアップデートやUFS1/UFS2のスナップショット機能も導入されており、これらは
NetBSDにも移植されています。
OpenBSDでは、2.9からソフトアップデート、4.2からUFS2をサポートしています。
4.4BSDとFreeBSD、
NetBSD、
OpenBSDなどのBSD系システムでは、UFS1とUFS2の実装は2つの層に分かれています。上位層は
ディレクトリ構造やinode内の
メタデータを扱い、下位層はデータコンテナを扱います。これはFFSとLFSの共通部分を共有するための仕組みです。上位層をUFS、下位層をFFSまたはLFSと呼びます。下位層にFFSを使用している場合は全体をFFS、LFSを使用している場合は全体をLFSと呼ぶことがあります。
Linuxでも、BSDとの互換性のためにUFSを実装していますが、UFSには共通の標準実装がないため、
Linuxでは主に読み込みがサポートされており、書き込みは完全にはサポートされていません。
Linuxのext2
ファイルシステムはUFSの影響を受けており、一部のシステムではUFSを上位層、ext2を下位層として使用できます。NeXTStepもBSDから派生しているためUFSを使用していましたが、macOSではHFS+の代替としてUFSを使用することができましたが、現在ではサポートされていません。