Sous Unix, généralement, un fichier est une entrée dans une table de fichiers. Il existe différents types de fichiers: fichiers normaux, périphériques, liens symboliques, portes, tuyaux, sockets, répertoires ...
Le numéro d'inode (que vous pouvez voir dans la sortie de ls -i
) est l'index de cette table.
Maintenant, vous n’accédez pas aux fichiers par inode mais par chemin . Un chemin est une chaîne d' entrées de répertoire . Vous remarquerez que nous ne parlons pas de dossier mais de répertoire ici. Parce que c'est ce qu'est un répertoire (pensez à un répertoire téléphonique).
Un répertoire est un type spécial de fichier qui donne des noms à un certain nombre d'inodes. Une entrée de répertoire est une correspondance entre un nom et un inode.
Un fichier donné (un inode) peut avoir plus d'un nom dans un répertoire (tout comme il peut y avoir plus d'un nom sur un numéro de téléphone), ainsi que des noms (entrées) dans plusieurs répertoires. Celles-ci sont appelées liens, également appelés liens durs, à distinguer des liens souples (un type spécial de fichier qui est un pointeur sur un chemin).
Un fichier (inode) garde trace du nombre de liens (d'entrées dans n'importe quel répertoire) qu'il possède. Ainsi, lorsque le nombre atteint 0 (lorsqu'il est dissocié du dernier répertoire dans lequel il a été référencé), il est désalloué.
C'est ce nombre (le nombre de liens) qui est affiché dans la ls -l
sortie.
Lorsqu'un fichier autre que de répertoire est créé pour la première fois (avec les appels système open
or creat
(ou or bind
ou mknod
pour certains types de fichiers)), vous devez indiquer un chemin d'accès au nouveau fichier (du type "/a/b"
). Il se passe alors un nouveau fichier, un inode est alloué et une nouvelle entrée est ajoutée au répertoire associé au "a"
nom figurant dans le "/"
répertoire racine. C'est le lien initial donc le nombre de liens est un.
Plus de liens peuvent être ajoutés ultérieurement avec l' link()
appel système (la ln
commande). Et les liens peuvent être supprimés avec l' unlink()
appel système (la rm
commande).
Vous remarquerez que les fichiers de type répertoire ont généralement un nombre de liens supérieur ou égal à 2.
Désormais, lorsque vous créez un répertoire, vous appelez l’ mkdir()
appel système. Quelque chose comme mkdir("/a/b")
. Ce qu’il fait alors est d’allouer un nouveau fichier de type répertoire. Dans ce nouveau répertoire, il crée automatiquement deux entrées:
"."
( point pour le répertoire ). Ce qui est un lien vers lui-même. Donc, le nombre de liens est maintenant 1.
".."
(pour le répertoire du répertoire ). Quel est un lien vers "/a"
. Donc, le nombre de liens de "/a"
est incrémenté de un
Ensuite, ce nouveau répertoire est lié à "/a"
(une entrée est ajoutée "/a"
pour celui-ci), donc son nombre de liens est maintenant 2. Si un "/a/b/c"
répertoire est créé, en raison de l' ".."
entrée "/a/b/c"
, le nombre de liens de "/a/b"
devient 3.
La plupart des Unices limitent la création de liens supplémentaires vers un répertoire car ils peuvent entraîner des boucles problématiques. Quand ils autorisent un link()
sur un répertoire, seul le superutilisateur peut le faire.
Certains systèmes de fichiers, par exemple, btrfs
s’écartent de cette structure de répertoires traditionnelle. Vous remarquerez que le nombre de liens sur les répertoires dans btrfs
les systèmes de fichiers est toujours égal à un, même si ces répertoires contiennent une "."
entrée avec le même numéro d'inode qu'eux-mêmes.
Le fait que le nombre de liens soit traditionnellement de 2 plus le nombre de sous-répertoires a son utilité. Par exemple, dans:
find . -name '*.c' -print
Si .
ne contient pas de sous-répertoires mais contient des millions de fichiers. En vérifiant le nombre de liens de .
, find
peut savoir qu'il n'y a pas de sous-répertoire. Il find
suffit donc de lire le contenu du répertoire et de rapporter les entrées qui se terminent .c
(comme un grep '\.c$'
fichier de quelques mégaoctets, ce n’est pas grave). Sinon, il find
faudrait vérifier le type de chaque fichier pour voir s’il existe des répertoires dans lesquels descendre (ce qui entraîne autant d’ lstat()
appels système). Bien sûr, ce type d’optimisation ne fonctionne pas btrfs
(bien que dans les versions modernes de Linux, le type de fichiers soit également stocké dans l’entrée du répertoire pour certains systèmes de fichiers (y compris btrfs
) et renvoyé par l’ getdents(2)
appel système utilisé pour récupérer la liste des entrées. dans un répertoire, donclstat
n'est toujours pas nécessaire).