Cours 2: Les fichiers: vue statique.
Le système de fichiers Unix est représenté par une arborescence. L'arbre est une
abstraction dont la réalisation physique se présente sous la forme d'un ensemble de
partitions de disques. Chaque partition est un système de fichiers à part entière.
L'assemblage des partitions pour former l'arborescence complète se fait dynamiquement en mémoire
et n'apparait en aucune façon sur le disque. La figure ci-dessous illustre le mappage d'une arborescence
en quatre partitions.
Dans l'exemple, les partitions Windows contiennent des structures Windows. La partition Swap contient la
zone de swap qui sert de mémoire réelle des processus. Les autres partitions Unix sont
formatées en système de fichiers Unix. La table des partitions qui figure en tête de chaque disque
décrit chaque partition sous forme d'un triplet (début, longueur, type).
Une partition formatée en SGF Unix se compose de quatre parties: le bloc de boot, le super-bloc, la table
des inodes et la zone des blocs de données.
Le bloc de boot n'est rempli que si la partition est une partition de démarrage (partition qui
contient une copie du noyau). Il contient un petit programme chargeant le noyau en mémoire et lui
donnant le contrôle.
Le super-bloc contient la taille de la zone des blocs de données, le nombre de blocs libres dans cette zone,
une table servant de tête de liste des blocs libres, la taille de la table des inodes, le nombre d'inodes libres,
une table contenant des numéros d'inodes libres et enfin l'état du super-bloc.
La zone des blocs de données est un mélange de blocs occupés et de blocs libres. Les blocs
occupés sont accessibles à partir de l'inode auquel ils appartiennent. Les blocs libres sont chaînés les uns aux autres, avec une amorce de la liste dans le super-bloc.
La figure ci-dessous montre la structure de la liste.
Dans chaque bloc de la liste, ainsi que dans le super-bloc, on trouve une table tnbl de numéros de blocs
libres (des blocs non chaînés dans la liste). Toutes ces tables ont la même taille. Chaque
entrée de table contient soit un numéro de bloc libre, soit 0 (entrée vide).
Voici comment on alloue un bloc:
Si la table tnbl du superbloc contient une entrée non nulle,
elle fournit directement le numéro du bloc alloué.
L'entrée correspondante est mise à zéro.
Sinon,
la table tnbl du premier bloc de la liste est chargée
dans celle (vide) du super-bloc.
Le bloc libre ainsi vidé de sa table tnbl est alloué.
La table tnbl du super-bloc est rechaînée
au successeur du bloc alloué.
Voici comment on libère un bloc:
Si la table tnbl du superbloc contient une entrée nulle,
le numéro du bloc libéré y est inscrit.
Sinon,
la table tnbl du super-bloc (pleine) est copiée
dans le bloc libéré.
Le bloc libéré est inséré en tête.
La table tnbl du super-bloc est vidée.
(elle pointe sur le bloc libéré).
La table des inodes est à accès direct (le numéro de l'inode désigne
son entrée dans la table). Les deux premières entrées sont inoccupées
(les numéros d'inode 0 et 1 sont inemployés). L'inode 2 (première entrée
occupée de la table) est la racine du SGF figurant dans la partition.
Un inode est une structure de taille fixe représentant un noeud de l'arborescence.
Un inode regroupe les champs suivants:
-l'identifiant du propriétaire (uid),
-l'identifiant du groupe propriétaire (gid),
-le type de l'inode (fichier, répertoire, spécial, tube, inode libre, ...),
-les droits (rwxrwxrwx),
-la date de dernière modification du fichier,
-la date de dernier accès au fichier,
-la date de dernière modification de l'inode,
-le nombre de liens,
-la table des blocs (13 entrées),
-la taille du fichier en octets.
Voici comment on alloue un inode:
Si la table tnil (table des numéros d'inodes libres)
du super-bloc contient une entrée non nulle,
le numéro de l'inode alloué y est inscrit.
Sinon,
on parcourt la table des inodes pour remplir la table tnil du super-bloc.
Chaque inode dont le type est 0 est libre.
Son numéro est ajouté à la table tnil.
Quand la table est pleine, le parcours s'achève.
Voici comment on libère un inode:
Si la table tnil contient une entrée nulle,
le numéro de l'inode libéré y est inscrit.
Le champ type de l'inode est mis à 0.
La figure suivante montre comment sont organisés les blocs de données d'un inode.
Rappelons que chaque inode contient dans la structure qui le décrit une table des blocs
à 13 entrées. Les 10 premières entrées donnent accès directement
aux dix premiers blocs de données. La onzième entrée donne accès à
un bloc prolongeant les dix premières entrées de la table. La douzième entrée donne accès à
un bloc prolongeant la onzième entrée. Enfin, la treizième entrée donne accès à
un bloc prolongeant la douzième entrée. Si un bloc peut contenir n numéros de blocs,
la table à 13 entrées permet de désigner au maximum (10 + n + n2 + n3)
blocs. Les 10 premiers sont accédés directement, les n suivants avec un niveau d'indirection,
les n2 suivants avec deux niveaux et les n3 derniers avec trois niveaux.
La structure abstraite de l'arborescence qui combine plusieurs partitions physiques est
constituée dynamiquement par le système (cette arborescence abstraite n'est donc pas
écrite sur le disque; elle est reconstituée à chaque fois que le système est démarré
et peut évoluer dynamiquement). Au démarrage du système, l'arborescence se réduit
à une partition: la partition de démarrage. Par la suite, divers scripts shell de configuration
montent (greffent) de nouvelles partitions soit sur la partition de démarrage, soit sur les partitions greffées.
Chaque greffe ajoute une ligne à une table des points de montage. La ligne précise la partition
greffée (disque, bloc de début), l'inode correspondant au point de greffe (un répertoire
de la partition sur laquelle s'opère la greffe) et la partition du point de greffe (disque, bloc de début). A chaque déplacement descendant dans l'arborescence, le noyau
cherche l'inode de destination dans la table des points de montage. S'il y est trouvé, le noyau change de partition.
De même, à chaque déplacement ascendant, si la racine de partition est atteinte (inode 2), la partition
courante est cherchée dans la table des points de montage, ce qui permet de retrouver la partition ascendante
(on est à la racine absolue si la partition courante est celle de démarrage).
Par exemple, la table des points de montage de l'arborescence abstraite de la figure 1 pourrait être
(en supposant que les répertoires usr, users et tmp aient les inodes 140, 220 et 300 dans la partition
de démarrage (partition p2 du disque d1)):
partition greffée inode partition du point de greffe
usr (d1, p3) /usr (140) (d1, p2)
users (d2, p2) /users (220) (d1, p2)
tmp (d2, p3) /tmp (300) (d1, p2)
En remontant à la racine (inode 2) de la partition (d2, p2) (i.e. users), on se retrouve dans la partition (d1, p2) (i.e. /),
inode 220. En descendant dans le répertoire /tmp (inode 300 de (d1, p2)), on se retrouve à la racine (inode 2)
de (d2, p3).