He visto muchas explicaciones de por qué el recuento de enlaces para un directorio vacío en sistemas operativos basados en Unix es 2 en lugar de 1. Todos dicen que se debe a '.' directorio, que cada directorio tiene apuntando a sí mismo. Entiendo por qué tener algún concepto de '.' es útil para especificar rutas relativas, pero ¿qué se gana al implementarlo a nivel de sistema de archivos? ¿Por qué no solo tener shells o las llamadas al sistema que toman caminos saben cómo interpretarlo?
Ese '...' es un enlace real que tiene mucho más sentido para mí: el sistema de archivos necesita almacenar un puntero de regreso al directorio padre para poder navegar hacia él. Pero no veo por qué '. Ser un enlace real es necesario. También parece que lleva a un caso especial feo en la implementación: pensaría que solo podría liberar el espacio utilizado por los inodos que tienen un recuento de enlaces inferior a 1, pero si son directorios, en realidad necesita verificar un enlace cuenta menos de 2. ¿Por qué la inconsistencia?
fuente
..
enlaces duros, su software para caminar por el árbol ya debe tener una excepción de "no seguir ciclos en el enlace del directorio principal" , por lo que se agrega poca complejidad a excepto el.
enlace.Respuestas:
Una pregunta interesante, de hecho. A primera vista veo las siguientes ventajas:
En primer lugar, declara que la interpretación "
.
" como el directorio actual puede ser realizada por el Shell o por llamadas del sistema. Pero tener la entrada de punto en el directorio en realidad elimina esta necesidad y fuerza la consistencia incluso en un nivel inferior.Pero no creo que esta fuera la idea básica detrás de esta decisión de diseño.
Cuando se crea o elimina un archivo de un directorio, también se debe actualizar la marca de tiempo de modificación del directorio. Esta marca de tiempo se almacena en su inodo. El número de inodo se almacena en la entrada del directorio correspondiente.
SI la entrada de puntos no estuviera allí, las rutinas tendrían que buscar el número de inodo en la entrada de este directorio en el directorio padre, lo que provocaría una búsqueda de directorio nuevamente.
PERO afortunadamente hay una entrada de punto en el directorio actual. La rutina que agrega o elimina un archivo en el directorio actual solo tiene que volver a la primera entrada (donde generalmente reside la entrada de puntos) e inmediatamente ha encontrado el número de inodo para el directorio actual.
Hay una tercera cosa buena sobre la entrada de puntos:
Cuando
fsck
verifica un sistema de archivos podrido y tiene que lidiar con bloques no conectados que tampoco están en la lista libre, es fácil para él verificar si un bloque de datos (cuando se interpreta como una lista de directorio) tiene una entrada de punto que apunta a un inodo que a su vez apunta a este bloque de datos. Si es así, este bloque de datos puede considerarse como un directorio perdido que debe volver a conectarse.fuente
.
en el directorio actual. A menos que pueda encontrar un núcleo donde realmente funcione de esta manera (lo dudo ...)(Hmm: lo siguiente ahora es un poco épico ...)
El diseño del directorio en los sistemas de archivos de Unix (que, para ser pedantes, están típicamente pero no necesariamente unidos a sistemas operativos de Unix) representa una visión maravillosa, que en realidad reduce el número de casos especiales requeridos.
Un 'directorio' es realmente solo un archivo en el sistema de archivos. Todo el contenido real de los archivos en el sistema de archivos está en inodes (de su pregunta, puedo ver que ya está al tanto de algunas de estas cosas). Los inodos en el disco no tienen estructura: son solo un gran grupo de gotas numeradas de bytes, esparcidas como mantequilla de maní sobre el disco. Esto no es útil, y de hecho es repelente para cualquier persona con una pizca de mentalidad ordenada.
La única inode especial es inode número 2 (no 0 o 1, por razones de tradición); inode 2 es un archivo de directorio: el directorio raíz . Cuando el sistema monta el sistema de archivos, "sabe" que tiene que leer el inodo 2 para comenzar.
Un archivo de directorio es solo un archivo, con una estructura interna que debe ser leída por opendir (3) y sus amigos. Puede ver su estructura interna documentada en dir (5) (dependiendo de su sistema operativo); si observa eso, verá que la entrada del archivo de directorio casi no contiene información sobre el archivo, todo eso está en el inodo del archivo. Una de las pocas cosas que tiene de especial este archivo es que la función open (2) generará un error si intenta abrir un archivo de directorio con un modo que permita la escritura. Varios otros comandos (para elegir solo un ejemplo
hexdump
) se negarán a actuar de la manera normal con los archivos de directorio, solo porque eso probablemente no sea lo que desea hacer (pero ese es su caso especial, no el del sistema de archivos).Un enlace duro no es más ni menos que una entrada en el mapa de un archivo de directorio. Puede tener dos (o más) entradas en dicho mapa que se mapean al mismo número de inodo: ese inodo, por lo tanto, tiene dos (o más) enlaces duros. Esto también explica por qué cada archivo tiene al menos un 'enlace duro'. El inodo tiene un recuento de referencia, que registra cuántas veces ese inodo se menciona en un archivo de directorio en algún lugar del sistema de archivos (este es el número que ve cuando lo hace
ls -l
).OK: estamos llegando al punto ahora.
El archivo de directorio es un mapa de cadenas ('nombres de archivo') a números (números de inodo). Esos números de inodo son los números de los inodes de los archivos que están 'en' ese directorio. Los archivos que están 'en' ese directorio pueden incluir otros archivos de directorio, por lo que sus números de inodo estarán entre los enumerados en el directorio. Por lo tanto, si tiene un archivo
/tmp/foo/bar
, el archivo de directoriofoo
incluye una entrada parabar
asignar esa cadena al inodo para ese archivo. También hay una entrada en el archivo de directorio/tmp
, para el archivo de directoriofoo
que está 'en' el directorio/tmp
.Cuando crea un directorio con mkdir (2), esa función
El resultado final es que (casi) los únicos casos especiales son:
st_mode
en stat (2).(copiado de la pregunta original de stackoverflow, 2011-10-20)
fuente