なぜ「。」Unixのハードリンク?


51

UnixベースのOSで空のディレクトリのリンクカウントが1ではなく2である理由については、多くの説明を見てきました。すべてのディレクトリがそれ自体を指しているディレクトリ。「。」という概念がある理由がわかります。相対パスを指定するには便利ですが、ファイルシステムレベルで実装すると何が得られますか?シェルまたはパスを取るシステムコールに、その解釈方法を知ってもらうだけではどうですか?

その「..」は本当のリンクです。ファイルシステムは、ナビゲートするために親ディレクトリへのポインタを保存する必要があります。しかし、「。」の理由がわかりません。実際のリンクであることが必要です。また、実装でい特別なケースにつながるようです-リンクカウントが1未満のiノードで使用されているスペースのみを解放できると思うでしょうが、それらがディレクトリの場合、実際にチェックする必要がありますリンクカウントが2未満。


1
あなたが持ってたら..、あなたのツリーウォーキング・ソフトウェアがすでに持っている必要がありますハードリンク「親ディレクトリリンクのない次のサイクル」それは少し除いても複雑に追加されるので、例外を.リンク。
dmckee

回答:


37

興味深い質問です。一見すると、次の利点があります。

まず.、現在のディレクトリとして" " を解釈することは、シェルまたはシステムコールによって行われる可能性があると述べています。ただし、ディレクトリにドットエントリを含めると、実際にはこの必要性がなくなり、さらに低いレベルで一貫性が強制されます。

しかし、これがこの設計決定の背後にある基本的なアイデアだとは思いません。

ファイルを作成したり、ディレクトリから削除したりするときは、ディレクトリの変更タイムスタンプも更新する必要があります。このタイムスタンプは、iノードに保存されます。iノード番号は、対応するディレクトリエントリに保存されます。

IFドットエントリは存在しないだろう、ルーチンは再びディレクトリ検索を引き起こすことになる、親ディレクトリで、このディレクトリのエントリでiノード番号を検索する必要があります。

しかし、幸いなことに、現在のディレクトリにドットエントリがあります。現在のディレクトリでファイルを追加または削除するルーチンは、最初のエントリ(通常はドットエントリが存在する場所)にジャンプするだけで、すぐに現在のディレクトリのiノード番号が見つかります。

ドットエントリには、3つ目の良い点があります。

ときにfsck空きリストにもありません非接続ブロックに対処するためのチェック腐ったファイルシステムをしてあり、それは(ディレクトリリストと解釈される)データブロックはiノードを指していますドットエントリを持っている場合、それは検証するために簡単です次に、このデータブロックをポイントします。その場合、このデータブロックは失われたディレクトリと見なされ、再接続する必要があります。


非常に便利な答え。
ナヴァニースKN

6
ディレクトリiノードを検索するルーチンについてのコメントは偽です。カーネルルーチンは.、現在のディレクトリを検索する必要はありません。実際にこの方法で動作するカーネルを見つけることができない場合(疑わしい...)
ディートリッヒEpp

1
@DietrichEppに同意します。システムが最初にディレクトリエントリを参照するには、iノードについて既に知っている必要があります。これは、ディレクトリエントリを含むデータブロックに到達する方法だからです。
Lqueryvg 14年

10

(うーん、次はちょっとした叙事詩です...)

UNIXファイルシステム上のディレクトリの設計(これは通常、UNIX OSに接続されますが、必ずしも必要ではありません)は素晴らしい洞察を表しており、実際に必要な特別なケースの数を減らします。

「ディレクトリ」は、実際にはファイルシステム内の単なるファイルです。ファイルシステム内のファイルの実際の内容はすべてiノードにあります(質問から、このようなもののいくつかを既に知っていることがわかります)。ディスク上のiノードには構造がありません。ディスク上のピーナッツバターのように広がっている、番号付きの大きな塊の単なる塊です。これは有用ではありません。そして、きちんと片付けられた人には本当に忌避です。

唯一の特殊なiノードは、(伝統の理由のためではない0または1)iノード番号2です。inode 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:これでポイントになりました。

ディレクトリファイルは、文字列(「ファイル名」)から数字(inode番号)へのマップです。これらのiノード番号は、そのディレクトリ内にあるファイルのiノードの番号です。そのディレクトリ内にあるファイルには、他のディレクトリファイルが含まれている可能性があるため、それらのiノード番号はディレクトリにリストされているものの中に含まれます。したがって、ファイル/tmp/foo/barがある場合、ディレクトリファイルにfooはのエントリが含まれ、barその文字列をそのファイルのiノードにマッピングします。ディレクトリファイル/tmpには、ディレクトリ内にfooあるディレクトリファイルのエントリもあります/tmp

mkdir(2)でディレクトリを作成すると、その機能

  1. 正しい内部構造を持つディレクトリファイル(iノード番号付き)を作成します。
  2. 親ディレクトリにエントリを追加し、新しいディレクトリの名前をこの新しいiノード(リンクの1つを占める)にマッピングします。
  3. 新しいディレクトリにエントリを追加し、文字列「。」をマッピングします 同じiノード(これは他のリンクを説明します)
  4. 新しいディレクトリに別のエントリを追加し、文字列「..」を手順(2)で変更したディレクトリファイルのinodeにマッピングします(これは、サブディレクトリを含むディレクトリファイルに表示される多数のハードリンクを説明します)。

最終結果は、(ほとんど)唯一の特別な場合です:

  • open(2)関数は、書き込みのためにディレクトリファイルを開かないようにすることで、自分自身を足で撃つことを困難にします。
  • mkdir(2)関数は、新しいディレクトリファイルにいくつかの追加エントリ(「。」および「..」)を追加することにより、物事を簡単かつ簡単にします。これは、純粋にファイルシステム内を移動できるようにするためです。「。」がなくてもファイルシステムは完璧に機能すると思います。および「..」ですが、使用するのは面倒です。
  • ディレクトリファイルは、「特別」としてフラグが付けられる数少ないタイプのファイルの1つです。これは、実際にopen(2)のようなものにわずかに異なる動作をさせるものです。st_modestat(2)を参照してください。

(stackoverflowの元の質問、2011年10月20日からコピー)


1
ブロックをiノードと混同しています。特殊なケースとして、短いファイルの場合、ファイルの内容はiノード内にあるかもしれませんが、iノードが構造化されていないことを主張するのは誤りです。それらは高度に構造化されており、ファイルが見つかる可能性のあるファイル名を除く、ほぼすべてのファイルメタデータを含んでいます。iノードには、ファイルの内容があるディスク上のブロックへのポインター(直接、間接、二重間接など)が含まれています。
フィルP

1
いいえ、ブロックをiノードと混同していません。iノードはブロックの上にある抽象概念であり、この投稿のポイントは、ファイルとディレクトリの関係、およびそれらのコンテンツを記述することでした。すべてのファイルシステム構造はディレクトリファイルに由来します。iノードの実装で行き詰まることなく、すでに十分な長さでした!(そうは言っても、最初の数段落をより明確に書くことができるかもしれません)。また、ご覧のとおり、ファイルに関するすべての情報(名前を除く)は、ディレクトリファイルではなく、inodeにあると明示的に述べています。
ノーマングレー

@NormanGray:あなたが自分自身を守るとしても、あなたは自分自身を足で撃ちます。「ファイルシステム内のファイルの実際のコンテンツはすべてinodeにある…」と言ったのは間違っています。  ファイルのプロパティ / 属性(所有者、許可、変更時刻など)はiノードに保存されます。通常のファイルの内容は、データブロックに格納されます。iノードの実装で行き詰まりたくない場合は、そうしないでください。ただし、誤解を招くような単純化を行わないでください。
G-Manは「Reinstate Monica」と言います
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.