Por que es '.' un enlace duro en Unix?

He visto muchas explicaciones de por qué el recuento de enlaces para un directory vacío en sistemas operativos basados ​​en Unix es 2 en lugar de 1. Todos dicen que es por el '.' directory, que cada directory tiene apuntando hacia sí mismo. Entiendo por qué tener algún concepto de '.' es útil para especificar routes relativas, pero ¿qué se gana al implementarlo en el nivel del sistema de files? ¿Por qué no solo tienen shells o las llamadas al sistema que toman paths saben cómo interpretarlo?

Ese '…' es un enlace real que tiene mucho más sentido para mí: el sistema de files necesita almacenar un puntero en el directory principal para navegar hacia él. Pero no veo por qué '.' ser un enlace real es necesario. También parece que conduce a un feo caso especial en la implementación: podrías pensar que solo puedes liberar el espacio utilizado por los inodos que tienen un número de enlaces inferior a 1, pero si son directorys, en realidad necesitas verificar un enlace count less de 2. ¿Por qué la inconsistencia?

Una pregunta interesante, de hecho. A primera vista veo las siguientes ventajas:

En primer lugar, debe indicar que interpreta " . " Ya que el Shell actual o las llamadas al sistema pueden realizar el directory actual. Pero tener la input de puntos en el directory en realidad elimina esta necesidad y fuerza la coinheritance incluso en un nivel inferior.

Pero no creo que esta sea la idea básica detrás de esta decisión de layout.

Cuando se crea o elimina un file de un directory, la timestamp de modificación del directory debe actualizarse también. Esta timestamp se almacena en su inodo. El número de inodo se almacena en la input del directory correspondiente.

SI la input de punto no estaría allí, las rutinas tendrían que search el número de inodo en la input de este directory en el directory principal, lo que causaría una búsqueda de directory nuevamente.

PERO, afortunadamente, está la input de puntos en el directory actual. La rutina que agrega o elimina un file en el directory actual solo tiene que volver a la primera input (donde normalmente reside la input de puntos) e inmediatamente ha encontrado el número de inodo para el directory actual.

Hay una tercera cosa agradable acerca de la input de puntos:

Cuando fsck comtesting un sistema de files podrido y tiene que lidiar con bloques no conectados que tampoco están en la list libre, es fácil para él verificar si un bloque de datos (cuando se interpreta como una list de directorys) tiene una input de punto que apunta a un inode que a su vez apunta a este bloque de datos. Si es así, este bloque de datos puede considerarse como un directory perdido que debe reconectarse.

(Hmm: el siguiente es ahora un poco épico …)

El layout del directory en los filesystems de Unix (que, para ser pedantes, están normalmente pero no necesariamente unidos a los SO de Unix) representa una visión maravillosa, que en realidad networkinguce la cantidad de casos especiales requeridos.

Un 'directory' es realmente solo un file en el sistema de files. Todo el contenido real de los files en el sistema de files está en inodos (de su pregunta, puedo ver que ya sabe algo de esto). No hay estructura para los inodos en el disco, son solo un gran grupo de bloques numerados de bytes, extendidos como manteca de maní sobre el disco. Esto no es útil, y de hecho es repelente para cualquier persona con una pizca de pulcritud.

El único inodo especial es el inodo número 2 (no 0 o 1, por razones de Tradición); inode 2 es un file de directory: el directory raíz . Cuando el sistema monta el sistema de files, 'sabe' que debe leer el inodo 2, para comenzar.

Un file de directory es solo un file, con una estructura interna que debe ser leída por opendir (3) y amigos. Puede ver su estructura interna documentada en dir (5) (dependiendo de su sistema operativo); Si observa eso, verá que la input del file de directory casi no contiene información sobre el file, eso está todo en el file inode. Una de las pocas cosas especiales de este file es que la function open (2) dará un error si intenta abrir un file de directory con un modo que permita la escritura. Varios otros commands (para elegir solo un ejemplo, hexdump ) se negarán a actuar de la manera normal con los files de directory, simplemente porque probablemente no sea lo que quieres hacer (pero ese es su caso especial, no el del sistema de files).

Un enlace fijo no es más que una input en el map de un file de directory. Puede tener dos (o más) inputs en dicho map que se correlacionan con el mismo número de inodo: ese inodo por lo tanto tiene dos (o más) enlaces duros. Esto también explica por qué cada file tiene al less un 'enlace duro'. El inodo tiene un recuento de reference, que registra cuántas veces se menciona ese inodo en un file de directory en algún lugar del sistema de files (este es el número que se ve cuando se hace ls -l ).

OK: estamos llegando al punto ahora.

El file de directory es un map de cadenas ('nombres de file') a numbers (numbers de inodo). Esos numbers de inodo son los numbers de los inodos de los files que están 'en' ese directory. Los files que están 'en' ese directory pueden include otros files de directory, por lo que sus numbers de inodo estarán entre los listdos en el directory. Por lo tanto, si tiene un file /tmp/foo/bar , entonces el file de directory foo incluye una input para la bar , asignando esa cadena al inodo para ese file. También hay una input en el file de directory /tmp , para el file de directory foo que está 'en' el directory /tmp .

Cuando creas un directory con mkdir (2), esa function

  1. crea un file de directory (con algún número de inodo) con la estructura interna correcta,
  2. agrega una input al directory padre, asignando el nombre del nuevo directory a este nuevo inodo (que representa uno de los enlaces),
  3. agrega una input al nuevo directory, mapeando la cadena '.' al mismo inodo (esto explica el otro enlace), y
  4. agrega otra input al nuevo directory, asignando la cadena '..' al inodo del file de directory que modificó en el paso (2) (esto representa la mayor cantidad de enlaces duros que verá en los files de directory que contienen subdirectorys )

El resultado final es que (casi) los únicos casos especiales son:

  • La function de apertura (2) intenta dificultar el disparo en el pie, impidiéndole abrir files de directory para escribir.
  • La function mkdir (2) hace que las cosas sean fáciles y fáciles al agregar un par de inputs adicionales ('.' Y '..') al nuevo file de directory, simplemente para hacer que sea conveniente moverse por el sistema de files. Sospecho que el sistema de files funcionaría perfectamente bien sin '.' y '..', pero sería un dolor de usar.
  • El file de directory es uno de los pocos types de files que están marcados como "especiales": esto es lo que realmente dice cosas como abrir (2) para comportarse de forma ligeramente diferente. Ver st_mode en stat (2).

(copydo de la pregunta original de stackoverflow, 2011-10-20)