The Second Extended Filesystem
==============================

ext2 は、1993 年 1 月に初めてリリースされました。R\'emy Card, Theodore
Ts'o, Stephen Tweedie によって書かれました。これは、Extended
Filesystem を大きく書き直したもので、Linux では現在 (2001 年 4 月) で
も有力なファイルシステムです。さらに NetBSD, FreeBSD, GNU HURD,
Windows 95/98/NT, OS/2, RISC OS で利用可能です。

オプション
==========

ext2 ファイルシステムをマウントする時、次のオプションが使用できます。
既定値は (*) と記しています。

bsddf                   (*)     df を BSD のように機能させます。
minixdf                         df を Minix のように機能させます。

check=none, nocheck     (*)     マウント時に過剰なビットマップのチェッ
                                クをしません。
                                (check=normal および check=strict オプ
                                ションは削除されました)

debug                           特別なデバッグ情報をカーネルの syslog
                                に送ります。開発者に役立ちます。

errors=continue         (*)     ファイルシステムのエラーがあっても実行
                                を続けます。
errors=remount-ro               エラーでファイルシステムを読み出し専用
                                として再マウントします。
errors=panic                    エラーが発生したなら、パニックしマシン
                                を停止 (halt) します。

grpid, bsdgroups                親と同じグループ ID をオブジェクトに与
                                えます。
nogrpid, sysvgroups     (*)     新しいオブジェクトは作成者のグループ
                                ID になります。

resuid=n                        留保されたブロックを使用可能なユーザ
                                ID
resgid=n                        留保されたブロックを使用可能なグループ
                                ID

sb=n                            この場所を代替スーパーブロックに使いま
                                す。

grpquota,noquota,quota,usrquota	Quota オプションは ext2 により警告なく
無視されます。


仕様
====

ext2 は伝統的な Unix ファイルシステムの多くの特性を継承しています。ブ
ロック、inode、ディレクトリの概念があります。仕様上、まだ実装されてい
ないアクセスコントロールリスト (ACL)、フラグメント、undeletion、圧縮の
ための領域も持っています (このうちのいくつかは個別のパッチで利用可能で
す)。さらに最大限の互換性を保ちながら、(ジャーナリングといった) 新しい
機能を追加するバージョニングの仕組みがあります。

ブロック
--------

デバイスやファイルの領域はブロックに分割されます。ブロックは 1024 か
2048, 4096 バイト (Alpha システムは 8192 バイトも選べます) の固定サイ
ズで、ファイルシステムの作成時に決められます。小さなブロックはファイル
毎の無駄な領域を減らしますが、多少管理のためのオーバヘッドを必要とし、
ファイルおよびファイルシステムのサイズ上の他の制限を課します。

ブロックグループ
----------------

大量の連続するデータを読む時のヘッドシークの量を最小にし、フラグメンテー
ションを減らすために、ブロックはブロックグループへ分割されます。各ブロッ
クグループの情報はスーパーブロックの直後のブロックに格納されたディスク
プリタテーブルに保持されます。各ブロックの先頭に近い二つのブロックは、
ブロックおよび inode のどれが使用中か示すビットマップに使うブロックと、
ビットマップに使う inode のために、予約されています。各ビットマップは
一つのブロックに制限されるので、ブロックグループの最大サイズはブロック
サイズの八倍になります。

各ブロックグループ内のビットマップに続くブロック (群) はブロックグルー
プ用の inode テーブルに、残りはデータブロックに割り当てられます。ブロッ
ク割当てのアルゴリズムはデータブロックを、それらを含む inode と同じブ
ロックグループ内に割当てようとします。

スーパーブロック
----------------

スーパーブロックはファイルシステムの構成のすべての情報を含みます。スー
パーブロックのプライマリコピーはデバイスの先頭から 1024 バイトのオフセッ
トで格納され、ファイルシステムをマウントするために不可欠なものです。こ
れはとても重要なものなので、スーパーブロックのバックアップコピーはファ
イルシステムに亘るすべてのブロックグループ内に格納されます。ext2 の最
初のバージョン (リビジョン 0) はすべてのブロックグループの先頭にグルー
プディスクプリタブロック (群) のバックアップと共にスーパーブロックのコ
ピーを格納します。これは大きなファイルシステムでは相当な量の領域を消費
するので、最新のリビジョンは特定のグループだけにバックアップを置くこと
で、任意にバックアップコピーの数を減らすことができます (スパーススーパー
ブロック機能です)。選ばれるグループは 0, 1 および 3, 5, 7 の累乗です。

スーパーブロック内の情報は、ファイルシステム内の inode および ブロック
の総数、フリーの数、各ブロックグループの inode およびブロックの数、ファ
イルシステムがいつマウントされたか (およびきれいにアンマウントされたか)、
ファイルシステムがいつ修正されたか、ファイルシステムのバージョンは何か
(以下のリビジョンセクションを参照してください)、どの OS で作成されたか、
といったフィールドがあります。

ファイルシステムがリビジョン 1 以上なら、ボリューム名、ユニークな識別
番号、inode のサイズ、任意なファイルシステム機能用の構成情報を格納する
領域、といった付加的なフィールドがあります。

スーパーブロック内のすべてのフィールドは (他の ext2 構造体と同様に) リ
トルエンディアン形式でディスク上に格納されるので、ファイルシステムはど
んなマシンで作られたか知る必要なしに、マシン間で移動することができます。

Inode
-----

inode (index node) は ext2 ファイルシステムの基本概念です。ファイルシ
ステム内の各オブジェクトは inode によって表わされます。inode 構造体は
ファイルシステムのブロックへのポインタを含み、そのブロックはオブジェク
ト内に保持されたデータおよび、オブジェクトに関するその名前以外のすべて
のメタデータを含みます。オブジェクトに関するメタデータはパーミッション、
所有者、グループ、フラグ、サイズ、使用ブロックの数、アクセス時刻、変更
時刻、修正時刻、削除時刻、リンクの数、フラグメント、バージョン (NFS 用)、
拡張属性 (EA) や Access Control List (ACL) を含みます。

inode 構造体には今のところ使われていない予約されたフィールドがあり、一
部は流用されてしまっています。あるフィールドは、inode がディレクトリな
らディレクトリ ACL 用に、inode が通常のファイルならファイルサイズの上
位 32 ビット用に (ファイルサイズが 2GB を超えられます)、予約されていま
す。トランスレータフィールドは Linux 下では未使用ですが、HURD は inode
を参照するためにこのオブジェクトを解釈するプログラムが使用します。予約
されたフィールドの残りのほとんどは所有者およびグループを拡張するフィー
ルドのために Linux と HURD の両方で使ってしまっています。さらに、HURD
には大きなモードフィールドがあるので、それ以外の残りのフィールドも多数
の追加ビットのために使っています。

inode には、ファイルのデータを保持する最初の 12 ブロックに対するポイン
タがいくつかあります。まず間接ブロック (次のブロック集合へのポインタが
含まれます) へのポインタ、二重間接ブロック (間接ブロックへのポインタが
含まれます) へのポインタ、そして三重間接ブロック (二重間接ブロックへの
ポインタが含まれます) へのポインタです。

フラグフィールドは標準の chmod フラグが提供していない ext2 固有なフラ
グを含みます。これらのフラグは lsattr コマンドで一覧および chattr コマ
ンドで変更でき、ファイル単位でファイルシステムに固有な振る舞いを行わせ
ます。安全な削除、削除の取り消し、圧縮、同期更新、不変性、追加専用、ダ
ンプ可能、atime なし、索引化されたディレクトリ、データジャーナリング、
のためのフラグがあります。まだ、これらのすべてがサポートされているとは
限りません。

ディレクトリ
------------

ディレクトリはファイルシステムのオブジェクトで、ちょうどファイルと同じ
ように inode を持ちます。これは、inode 番号にそれぞれの名前を関連させ
るレコードを含んだ特別なフォーマットを持つファイルです。さらに、ファイ
ルシステムの新しいリビジョンではオブジェクトの種類 (ファイル、ディレク
トリ、シンボリックリンク、デバイス、fifo, ソケット) をコード化し、この
情報のために inode 自身をチェックしなくてもよいようにします (この機能
を活用するためのサポートは Glibc 2.2 ではまだありません)。

inode の配置コードは inode をそれらが最初に作成されたディレクトリと同
じブロックグループ内に割当てようとします。

ext2 の現在の実装はディレクトリにファイル名を格納するために単方向リン
クのリストを使います - ディレクトリ全体を走査せずにファイルを探すため、
ファイル名のハッシュを使う機能拡張が懸案となっています。

より多くのファイルを保持するためにディレクトリブロックが割当てられたな
らば、現在の実装はその領域が空になっても空きブロックを削除しません。

スペシャルファイル
------------------

シンボリックリンクもまた inode を伴ったファイルシステムのオブジェクト
です。シンボリックリンク長が 60 バイトより短ければ、シンボリックリンク
のデータは inode 自身に格納されるので、それについて特記します。それは
データブロックへのポインタを格納するために通常使用されるフィールドを使
います。これはシンボリックリンクにブロック一つを割当てることを回避する
価値のある最適化で、ほとんどのシンボリックリンク長は 60 文字未満です。

キャラクタおよびブロックのスペシャルデバイスにデータブロックが割当てら
れることはありません。代わりに、それらのデバイス番号は inode 内に格納
され、データブロックを指すために使われるフィールドがここでも使われます。

留保された領域
--------------

ext2 では、特定のユーザ (通常スーパーユーザ) のために幾らかのブロック
を取っておく仕組みがあります。これは、特権の無いユーザが彼らにとって利
用可能な領域をすべて埋め尽くしてしまっても、システムが機能し続けること
を意図しています。さらに、ファイルシステムが埋め尽くされることを防ぎま
す。これはフラグメンテーション対策に有効です。

ファイルシステムチェック
------------------------

ブート時にほとんどのシステムはファイルシステム上の一貫性チェック
(e2fsck) を実行します。(ファイルシステムが大きければブート時にそれを
チェックするのに長い時間かかるかもしれないので) ext2 ファイルシステム
のスーパーブロックは実際に fsck を実行するべきかどうかを示すいくつかの
フィールドを持っています。fsck が実行されるのは、ファイルシステムがき
れいにアンマウントされなかった場合、最大マウント回数を超過した場合、
チェック間の最大時間を超過した場合です。

機能の互換性
------------

ext2 で使用される互換性機能の仕組みは洗練されています。ファイルシステ
ムのコードの古いバージョンとの互換性を犠牲にすることなく、ファイルシス
テムに機能を安全に追加できます。機能の互換性の仕組みは ext2 のオリジナ
ルのリビジョン 0 (EXT2_GOOD_OLD_REV) ではサポートされませんが、リビジョ
ン 1 から導入されました。互換性のある機能用 (COMPAT)、読み出し専用の互
換性のある機能用 (RO_COMPAT)、互換性のない機能用 (INCOMPAT) の三つの
32 ビットフィールドがあります。

これらの機能フラグは以下に示すカーネル向けの特定の意味を持っています -

COMPAT フラグは、機能がファイルシステムの中にあることを示し、ディスク
上のフォーマットが古いディスク上のフォーマットと 100% 互換性があるので、
この機能についてカーネルが何も知らなくても、ファイルシステムを破壊する
ことなく (さらには一貫性を失わせることさえなく)、ファイルシステムを読
み書きできます。これは本質的に、カーネルもしくは e2fsck が注意すべき
「このファイルシステムは (隠された) 機能があります」と言う単なるフラグ
です (e2fsck と機能フラグについては後述します)。ext3 ジャーナルはデー
タブロックを保持した単なる普通のファイルなので、ext3 の HAS_JOURNAL 機
能は COMPAT フラグです。したがって、カーネルが ext3 ジャーナリングを理
解しなくても、どんな特別な注意も払う必要がありません。

RO_COMPAT フラグはディスク上のフォーマットが古いディスク上のフォーマッ
トと読み出しについて 100% 互換性があることを示します (つまり、ディスク
上のフォーマットの見かけ上の機能は変わりません)。しかしながら、古いカー
ネルからファイルシステムに書き込んだ時にファイルシステムを破壊してしま
う場合があるため、書込みは阻止されます。こういった機能のうち最も一般的
なものである SPARSE_SUPER は RO_COMPAT 機能で、スパースグループはスー
パーブロック／グループのディスクプリタを示すためにファイルのデータブロッ
クを使用させ、ext2_free_blocks() は矛盾したビットマップを引き起こすこ
れらのブロックの解放処理を拒否します。さらに古いカーネルがグループ境界
を横断した一連のブロックを解放しようとすれば、エラーになりますが、これ
は SPARSE_SUPER ファイルシステムでは正当なファイル配置です。

INCOMPAT フラグはディスク上のフォーマットが、古いカーネルで判読不能に
された、もしくは古いカーネルがマウントしようとすると問題が起きる方法で、
変更されたことを示します。FILETYPE は古いカーネルが、ファイル名は 256
文字以上だったと考え、誤ったディレクトリ一覧を行う原因になるので、
INCOMPAT フラグです。COMPRESSION は明確に INCOMPAT フラグです - カーネ
ルが圧縮を理解しなければ、自動的にデータを伸張する代わりに、read() は
ゴミのようなものを返すでしょう。ext3 の RECOVER フラグは、ext3 ジャー
ナルを理解しないカーネルが、ジャーナルをリプレイすることなくファイルシ
ステムをマウントすることを防ぐために必要とされます。

e2fsck では、これらフラグの取り扱いをカーネルより厳しくする必要があり
ます。COMPAT, RO_COMPAT, INCOMPAT フラグのどれかを理解しなければ、与え
られている機能が有効か否か確認する方法がないので、ファイルシステムのチェ
ックを拒否します。未知の機能を持ったファイルシステム上で e2fsck を行っ
てしまうことは、ユーザにとって安全面で誤った判断です。未知の機能を持っ
たファイルシステムのチェックを拒否することは、ユーザが最新の e2fsck へ
更新するための良い動機になります。さらに誰かが機能フラグを ext2 へ追加
することは、これらの機能を確認するために、e2fsck の更新も必要だという
ことを意味します。

メタデータ
----------

非同期にメタデータを書く ext2 の実装は、ffs の同期メタデータの仕組みよ
り速いが信頼性にかけると頻繁に主張されます。二つの方法はそれぞれの
fsck プログラムにより等しく解決できるものです。

どうしても行いたければ、ext2 上にメタデータを同期して書かせる方法が三
つあります -

プログラムソースがあれば、ファイル毎に - open() で O_SYNC フラグを使っ
てください。
プログラムソースがなければ、ファイル毎に - ファイルに対し "chattr +S"
を使ってください。
ファイルシステム毎に - マウントオプション (あるいは /etc/fstab の中)
に "sync" を追加してください。

最初と最後のものは ext2 固有ではありませんが、強制的にメタデータを同期
して書き込みます。以下のジャーナリングも参照してください。

制限
----

ext2 にはディスク上のデータ構造設計によって課された様々な制限がありま
す。他の制限はカーネルコードの現行の実装によって課されます。制限の多く
はファイルシステムが始めて作成された時に決められ、選ばれたブロックサイ
ズに依存します。inode のデータブロックに対する比率はファイルシステム作
成時に固定されていますので、inode の数を増加させるただ一つの方法はファ
イルシステムのサイズを増加させることです。inode のブロックに対する比率
を変更できるツールは今のところありません。

ディスク上のフォーマットの少しの変更とフォーマットの変更を示す互換性フ
ラグを用いることで (多少の互換性を犠牲にして)、これら制限のほとんどを
克服することができるかもしれません。

ファイルシステムのブロックサイズ     1kB     2kB      4kB      8kB

ファイルサイズの制限                16GB   256GB   2048GB   2048GB
ファイルシステムサイズの制限      2047GB  8192GB  16384GB  32768GB

2.4 カーネルには、単一のブロックデバイスで 2048GB の制限があるので、現
時点で、これより大きいファイルシステムを作成することはできません。さら
にカーネルのページサイズによって課されたブロックサイズの上限があり、
8kB ブロックは Alpha (および大きなページをサポートする他のアーキテクチャ)
システム上だけで許されます。

一つのディレクトリに 32768 のサブディレクトリの上限があります。

現行の単方向リンクのリストによるディレクトリの実装で、一つのディレクト
リ内のファイル数は、実運用上約 10-15k 個が上限になります。この制限はこ
のような大きなディレクトリ内のファイルを作成および削除 (さらに検索) す
る時のパフォーマンスの問題のためです。ディレクトリインデックスのハッシ
ング (開発中) を使用すれば、パフォーマンスの問題なしに一つのディレクト
リに 100k-1M+ 個のファイルが置けます (この時には RAM サイズが問題にな
ります)。

一つのディレクトリ内のファイルの (無意味な) 絶対的な上限 (ファイルサイ
ズによって課されるもので、現実的な制限は明白にはるかに少ない) は 130
兆ファイル以上です。ユニークなディレクトリエントリを構築するための名前
は 4 文字では足りないので、8 文字のファイル名にしなければならないとい
うことを考慮しなければもっと多くできますが、考慮してすらユニークなファ
イル名を使い果たしてしまいそうです。

ジャーナリング
--------------

ext2 コードに対するジャーナリングの拡張は Stephen Tweedie によって開発
されました。ext2 でディスク上の配置変更を要せず、メタデータの破壊のリ
スクおよびクラッシュ後復旧するための e2fsck の実行を待つ必要性を回避し
ます。簡単に言うと、修正のあったメタデータブロック (およびデータブロッ
クも対象にできます) 全体をファイルシステムに書き込む前に、それらを格納
する普通のファイルがジャーナルです。これは既存の ext2 ファイルシステム
のデータ変換を必要とすることなく、それにジャーナルを追加できることを意
味します。

ファイルシステムを変更する時 (例えばファイル名の変更)、それらはジャー
ナル内のトランザクションの中に格納され、クラッシュの時に complete か
incomplete のどちらかになります。クラッシュの時 (もしくはシステムがク
ラッシュしていない正常な場合) に、このトランザクションが complete なら、
トランザクションの中のすべてのブロックは有効なファイルシステムの状態を
表していることを保証され、ファイルシステム内にコピーされます。クラッシュ
の時にトランザクションが incomplete なら、トランザクションの中のブロッ
クに一貫性の保証がないのでそれらは破棄されます (それらが表すファイルシ
ステムのどんな変更も失われることを意味します)。

ext3 コードは現在 (2001 年 4 月) 2.2 カーネル用だけ利用可能で、2.4 カー
ネルではまだ利用できません。

情報源
======

The kernel source       file:/usr/src/linux/fs/ext2/
e2fsprogs (e2fsck)      http://e2fsprogs.sourceforge.net/
Design & Implementation http://e2fsprogs.sourceforge.net/ext2intro.html
Journaling (ext3)       ftp://ftp.uk.linux.org/pub/linux/sct/fs/jfs/
Hashed Directories      http://kernelnewbies.org/~phillips/htree/
Filesystem Resizing     http://ext2resize.sourceforge.net/
Extended Attributes &
Access Control Lists    http://acl.bestbits.at/
Compression (*)         http://www.netspace.net.au/~reiter/e2compr/

実装関連：
Windows 95/98/NT/2000   http://uranus.it.swin.edu.au/~jn/linux/Explore2fs.htm
Windows 95 (*)          http://www.yipton.demon.co.uk/content.html#FSDEXT2
DOS client (*)          ftp://metalab.unc.edu/pub/Linux/system/filesystems/ext2/
OS/2                    http://perso.wanadoo.fr/matthieu.willm/ext2-os2/
RISC OS client          ftp://ftp.barnet.ac.uk/pub/acorn/armlinux/iscafs/

(*) (2001 年 4 月の時点で) もう開発もサポートも行っていません。
======================================================================
日本語訳：野本浩一 <hng@ps.ksky.ne.jp>
    校正：Seiji Kanekoさん <skaneko@a2.mbn.or.jp>
          岡本直さん <azure@kcc.zaq.ne.jp>
