(うーん:以下はちょっと叙事詩です...)
UNIXファイルシステム上のディレクトリの設計(これは、通常、UNIX OSに接続されている必要はありませんが)は素晴らしい洞察を表しており、実際に必要な特殊なケースの数を減らします。
「ディレクトリ」は、実際にはファイルシステム内の単なるファイルです。ファイルシステム内のファイルの実際のコンテンツはすべてinodeになっています(あなたの質問から、あなたはすでにこのようなもののいくつかを知っていることがわかります)。ディスク上のiノードには構造がありません。これらは、ディスク上にピーナッツバターのように広がった、番号が付けられたバイトの大きな塊にすぎません。これは役に立ちません、そして確かにきちんとした心の断片を持っている人には忌避します。
唯一の特別なiノードはiノード番号2です(伝統上の理由から0または1ではありません)。iノード2はディレクトリファイルです:ルートディレクトリ。システムがファイルシステムをマウントするとき、システムはそれ自体を開始するためにiノード2をreaddirする必要があることを「認識」します。
ディレクトリファイルは、opendir(3)やその仲間が読み取ることを目的とした内部構造を持つ単なるファイルです。dir(5)に記載されている内部構造を確認できます(OSによって異なります)。これを見ると、ディレクトリファイルエントリにファイルに関する情報がほとんど含まれていないことがわかります。これはすべてファイルiノードに含まれています。このファイルの特別な点の1つは、書き込みを許可するモードでディレクトリファイルを開こうとすると、open(2)関数でエラーが発生することです。他のさまざまなコマンド(1つの例を選択hexdump
するため)は、ディレクトリファイルに対して通常の方法で動作することを拒否します。これは、おそらくそれが実行したいことではないためです(ただし、これはファイルシステムではなく、特殊なケースです)。
ハードリンクは、ディレクトリファイルのマップ内のエントリにすぎません。このようなマップには、両方が同じiノード番号にマップされる2つ(またはそれ以上)のエントリを含めることができます。したがって、そのiノードには2つ(またはそれ以上)のハードリンクがあります。これは、すべてのファイルに少なくとも1つの「ハードリンク」がある理由も説明しています。iノードには参照カウントがあり、ファイルシステムのどこかにあるディレクトリファイルでそのiノードが言及された回数を記録します(これは、実行したときに表示される数ですls -l
)。
OK:今、要点に到達しています。
ディレクトリファイルは、文字列('filenames')から数値(iノード番号)へのマップです。これらのiノード番号は、そのディレクトリにあるファイルのiノードの番号です。そのディレクトリにあるファイルには他のディレクトリファイルが含まれている可能性があるため、それらのiノード番号はディレクトリにリストされているファイルの中に含まれます。したがって、ファイルがある/tmp/foo/bar
場合、ディレクトリファイルfoo
にはのエントリが含まれ、bar
その文字列をそのファイルのiノードにマッピングします。/tmp
ディレクトリファイルには、ディレクトリ内にfoo
あるディレクトリファイルのエントリもあります/tmp
。
mkdir(2)を使用してディレクトリを作成すると、その機能が実行されます
- 正しい内部構造を持つディレクトリファイル(iノード番号付き)を作成し、
- 親ディレクトリにエントリを追加し、新しいディレクトリの名前をこの新しいiノード(リンクの1つを占める)にマッピングします。
- 文字列'。'をマッピングして、新しいディレクトリにエントリを追加します。同じiノード(これは他のリンクを説明します)に、そして
- 新しいディレクトリに別のエントリを追加し、文字列'..'を手順(2)で変更したディレクトリファイルのiノードにマッピングします(これは、サブディレクトリを含むディレクトリファイルに表示されるハードリンクの数が多いことを示しています。 )。
最終的な結果は、(ほぼ)唯一の特殊なケースは次のとおりです。
- open(2)関数は、書き込み用にディレクトリファイルを開かないようにすることで、自分の足を撃ちにくくしようとします。
- mkdir(2)関数は、ファイルシステム内を移動しやすくするために、新しいディレクトリファイルにいくつかのエントリ(「。」と「..」)を追加することで、作業を簡単にします。ファイルシステムは「。」がなくても完全に機能すると思います。および「..」ですが、使用するのは面倒です。
- ディレクトリファイルは、「特別」としてフラグが付けられた数少ないタイプのファイルの1つです。これは、open(2)などの動作が少し異なることを実際に示しています。
st_mode
stat(2)を参照してください。