Warum ist '.' ein fester Link in Unix?


51

Ich habe viele Erklärungen dafür gesehen, warum die Linkanzahl für ein leeres Verzeichnis in Unix-basierten Betriebssystemen 2 statt 1 ist. Verzeichnis, das jedes Verzeichnis auf sich selbst verweist. Ich verstehe, warum ein Konzept von "." ist nützlich für die Angabe relativer Pfade, aber was bringt die Implementierung auf Dateisystemebene? Warum nicht einfach Muscheln oder Systemaufrufe, die Pfade nehmen, wissen, wie man sie interpretiert?

Das '..' ist ein echter Link, der für mich viel sinnvoller ist - das Dateisystem muss einen Zeiger zurück zum übergeordneten Verzeichnis speichern, um dorthin zu navigieren. Aber ich verstehe nicht warum. eine echte Verbindung zu sein ist notwendig. Es sieht auch so aus, als würde dies zu einem hässlichen Sonderfall in der Implementierung führen - man könnte denken, man könnte nur den Speicherplatz freigeben, der von Inodes mit einer Linkanzahl von weniger als 1 verwendet wird, aber wenn es sich um Verzeichnisse handelt, müssen Sie tatsächlich nachsehen eine Linkanzahl kleiner als 2. Warum die Inkonsistenz?


1
Sobald Sie über die ..Hardlinks verfügen, muss Ihre Tree-Walking-Software bereits die Ausnahmen "Nicht den Zyklen der übergeordneten Verzeichnisverknüpfung folgen" aufweisen , sodass es nur wenig komplizierter ist, auch die .Verknüpfung auszuschließen.
dmckee

Antworten:


37

Eine interessante Frage. Auf den ersten Blick sehe ich folgende Vorteile:

Zunächst geben Sie an, dass die Interpretation " ." als aktuelles Verzeichnis von der Shell oder durch Systemaufrufe erfolgen kann. Der Punkteintrag im Verzeichnis beseitigt jedoch diese Notwendigkeit und erzwingt eine Konsistenz auf einer noch niedrigeren Ebene.

Aber ich glaube nicht, dass dies die Grundidee hinter dieser Designentscheidung war.

Wenn eine Datei in einem Verzeichnis erstellt oder daraus entfernt wird, muss auch der Änderungszeitstempel des Verzeichnisses aktualisiert werden. Dieser Zeitstempel wird in seinem Inode gespeichert. Die Inode-Nummer wird im entsprechenden Verzeichniseintrag gespeichert.

Wäre der Punkteintrag nicht vorhanden, müssten die Routinen nach der Inode-Nummer am Eintrag für dieses Verzeichnis im übergeordneten Verzeichnis suchen, was eine erneute Verzeichnissuche zur Folge hätte.

ABER zum Glück gibt es den Punkteintrag im aktuellen Verzeichnis. Die Routine, die eine Datei im aktuellen Verzeichnis hinzufügt oder entfernt, muss nur zum ersten Eintrag (in dem sich normalerweise der Punkteintrag befindet) zurückspringen und hat sofort die Inode-Nummer für das aktuelle Verzeichnis gefunden.

Es gibt eine dritte nette Sache über den Punkteintrag:

Wenn fsckein verrottetes Dateisystem überprüft wird und nicht verbundene Blöcke behandelt werden müssen, die ebenfalls nicht in der Liste der freien Blöcke enthalten sind, kann auf einfache Weise überprüft werden, ob ein Datenblock (wenn er als Verzeichnisliste interpretiert wird) einen Punkteintrag enthält, der auf eine Inode verweist was wiederum auf diesen Datenblock zurückweist. In diesem Fall kann dieser Datenblock als verlorenes Verzeichnis betrachtet werden, das erneut verbunden werden muss.


Sehr nützliche Antwort.
Navaneeth KN

6
Der Kommentar zu Routinen, die nach dem Verzeichnis inode suchen, ist falsch. Kernel-Routinen müssen nicht .im aktuellen Verzeichnis nachschlagen . Es sei denn, Sie finden einen Kernel, in dem es tatsächlich so funktioniert (ich bezweifle es ...)
Dietrich Epp

1
Ich bin einverstanden mit @DietrichEpp; Damit das System die Verzeichniseinträge zuerst betrachten kann , muss es bereits über den Inode informiert sein - denn so gelangt es zu den Datenblöcken, die die Verzeichniseinträge enthalten.
Lqueryvg

10

(Hmm: das folgende ist jetzt ein bisschen episch ...)

Das Design des Verzeichnisses auf Unix-Dateisystemen (die normalerweise, aber nicht unbedingt, mit Unix-Betriebssystemen verknüpft sind) bietet einen wunderbaren Einblick, der die Anzahl der erforderlichen Sonderfälle verringert.

Ein 'Verzeichnis' ist eigentlich nur eine Datei im Dateisystem. Der gesamte tatsächliche Inhalt der Dateien im Dateisystem befindet sich in Inodes (aus Ihrer Frage kann ich ersehen, dass Ihnen einige dieser Dinge bereits bekannt sind). Die Inodes auf der Festplatte sind nicht strukturiert - es handelt sich lediglich um eine große Menge nummerierter Bytes, die wie Erdnussbutter auf der Festplatte verteilt sind. Dies ist nicht sinnvoll und in der Tat abstoßend für alle, die etwas aufgeräumt sind.

Der einzige spezielle Inode ist Inode Nummer 2 (aus Traditionsgründen nicht 0 oder 1); Inode 2 ist eine Verzeichnisdatei: das Stammverzeichnis . Wenn das System das Dateisystem einbindet, "weiß" es, dass es das Verzeichnis inode 2 lesen muss, um sich selbst zu starten.

Eine Verzeichnisdatei ist nur eine Datei mit einer internen Struktur, die von opendir (3) und Freunden gelesen werden soll. Sie können die interne Struktur in dir (5) sehen (abhängig von Ihrem Betriebssystem). Wenn Sie sich das ansehen, werden Sie sehen, dass der Verzeichnisdateieintrag fast keine Informationen über die Datei enthält - das ist alles in der Datei inode. Eine der wenigen Besonderheiten dieser Datei ist, dass die open (2) -Funktion einen Fehler ausgibt, wenn Sie versuchen, eine Verzeichnisdatei in einem Modus zu öffnen, der das Schreiben zulässt. Verschiedene andere Befehle (um nur ein Beispiel zu nennen hexdump) lehnen es ab, auf die normale Weise mit Verzeichnisdateien umzugehen, nur weil dies wahrscheinlich nicht das ist, was Sie tun möchten (aber das ist ihr Spezialfall, nicht der des Dateisystems).

Ein fester Link ist nichts anderes als ein Eintrag in der Map einer Verzeichnisdatei. Sie können zwei (oder mehr) Einträge in einer solchen Zuordnung haben, die beide derselben Inode-Nummer zugeordnet sind: Diese Inode hat daher zwei (oder mehr) feste Verknüpfungen. Dies erklärt auch, warum jede Datei mindestens einen "Hardlink" hat. Der Inode hat einen Referenzzähler, der aufzeichnet, wie oft dieser Inode in einer Verzeichnisdatei irgendwo im Dateisystem erwähnt wird (dies ist die Zahl, die Sie sehen, wenn Sie dies tun ls -l).

OK: Wir kommen jetzt auf den Punkt.

Die Verzeichnisdatei ist eine Zuordnung von Zeichenfolgen ('Dateinamen') zu Zahlen (Inode-Nummern). Diese Inode-Nummern sind die Nummern der Inodes der Dateien, die sich in diesem Verzeichnis befinden. Die Dateien, die sich in diesem Verzeichnis befinden, können auch andere Verzeichnisdateien enthalten, sodass ihre Inode-Nummern zu den im Verzeichnis aufgelisteten gehören. Wenn Sie also eine Datei haben /tmp/foo/bar, enthält die Verzeichnisdatei fooeinen Eintrag für barund ordnet diese Zeichenfolge dem Inode für diese Datei zu. Es gibt auch einen Eintrag in der Verzeichnisdatei /tmpfür die Verzeichnisdatei, foodie sich im Verzeichnis befindet /tmp.

Wenn Sie ein Verzeichnis mit mkdir (2) erstellen, funktioniert diese Funktion

  1. erstellt eine Verzeichnisdatei (mit einer Inode-Nummer) mit der korrekten internen Struktur,
  2. Fügt einen Eintrag zum übergeordneten Verzeichnis hinzu und ordnet den Namen des neuen Verzeichnisses diesem neuen Inode zu (der einen der Links berücksichtigt).
  3. Fügt dem neuen Verzeichnis einen Eintrag hinzu und ordnet die Zeichenfolge '.' zum selben Inode (dies ist der andere Link) und
  4. fügt dem neuen Verzeichnis einen weiteren Eintrag hinzu und ordnet die Zeichenfolge '..' dem Inode der in Schritt (2) geänderten Verzeichnisdatei zu (dies erklärt die größere Anzahl von Hardlinks, die Sie für Verzeichnisdateien mit Unterverzeichnissen sehen ).

Das Endergebnis ist, dass (fast) die einzigen Sonderfälle sind:

  • Die open (2) -Funktion versucht es schwieriger zu machen, sich in den Fuß zu schießen, indem verhindert wird, dass Sie Verzeichnisdateien zum Schreiben öffnen.
  • Die Funktion mkdir (2) vereinfacht die Arbeit, indem der neuen Verzeichnisdatei ein paar zusätzliche Einträge ('.' Und '..') hinzugefügt werden, um das Navigieren im Dateisystem zu vereinfachen. Ich vermute, dass das Dateisystem ohne '.' und "..", aber es wäre ein Schmerz zu benutzen.
  • Die Verzeichnisdatei ist einer der wenigen Dateitypen, die als "speziell" gekennzeichnet sind - genau das weist Dinge wie open (2) an, sich etwas anders zu verhalten. Siehe st_modein stat (2).

(kopiert von der ursprünglichen Frage zum Stapelüberlauf, 20.10.2011)


1
Sie verwechseln Blöcke mit Inodes. Als Sonderfall, für kurze Dateien, Dateiinhalt könnte innerhalb der inode sein, aber es ist falsch zu behaupten , dass Inodes unstrukturiert ist. Sie sind stark strukturiert und enthalten fast alle Dateimetadaten mit Ausnahme der Dateinamen, anhand derer die Datei möglicherweise gefunden wird. Der Inode enthält Zeiger (direkt, indirekt, doppelt indirekt usw.) auf die Blöcke auf der Festplatte, auf denen sich der Dateiinhalt befindet.
Phil P

1
Nein, ich verwechsle keine Blöcke mit Inodes. Die Inodes sind eine Abstraktion, die über Blöcken liegt, und der Zweck dieses Beitrags bestand darin, die Beziehung zwischen den Dateien und Verzeichnissen und deren Inhalt zu beschreiben: Die gesamte Dateisystemstruktur stammt aus den Verzeichnisdateien. Es war lange genug, ohne sich in Inode-Implementierungen festzusetzen! (das heißt, ich könnte möglicherweise die ersten paar Absätze klarer schreiben). Wie Sie sehen, erkläre ich ausdrücklich, dass sich alle Informationen über die Datei (mit Ausnahme ihres Namens) im Inode und nicht in der Verzeichnisdatei befinden.
Norman Gray

@NormanGray: Selbst wenn du dich verteidigst, schießt du dir in den Fuß. Sie sagten: "Der gesamte Inhalt der Dateien im Dateisystem befindet sich in Inodes." Das ist falsch.  Eigenschaften / Attribute einer Datei (z. B. Eigentümer, Berechtigungen, Änderungszeitpunkt usw.) werden im Inode gespeichert. Der Inhalt einer normalen Datei wird in Datenblöcken gespeichert. Wenn Sie sich nicht in Inode-Implementierungen festsetzen wollen, dann tun Sie das nicht, aber machen Sie bitte auch keine irreführenden Vereinfachungen.
G-Man sagt, dass Monica am
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.