Chapitre 1 · 5 h
Système de fichiers
Fichier, répertoire et chemin ; droits et propriétaires ; blocs, inodes et FAT ; montage, et journalisation en survol.
Sous Unix, on peut supprimer un fichier qu'un programme est en train de lire. Le programme continue de lire, jusqu'au bout, sans erreur — et l'espace n'est libéré qu'à sa fermeture. Sous Windows, la même opération est refusée : le fichier est verrouillé.
Cette différence n'est pas un détail d'implémentation. Elle révèle ce qu'est réellement un
fichier dans un système Unix : le nom et le contenu sont deux objets distincts. rm
n'efface rien, il retire un nom. Le contenu disparaît quand plus personne n'y renvoie.
Ce chapitre décrit cette organisation. Il ferme la boucle du cours : le chapitre 6 rangeait des pages sur un disque sans dire comment ce disque était structuré, et la mémoire virtuelle suppose exactement ce que nous allons construire.
Fichier, répertoire, chemin
Un fichier est une suite d'octets nommée et persistante. C'est tout — le système ne connaît
ni « fichier texte », ni « image ». L'extension .jpg est une convention entre applications, et
la commande file, qui reconnaît un format, le fait en examinant les premiers octets, pas le
nom.
Un répertoire est un fichier lui aussi, dont le contenu est une table de correspondances entre des noms et des numéros. Ces numéros sont ceux des inodes, et c'est la structure centrale du chapitre.
Répertoire /home/ana┌────────────┬────────┐│ nom │ inode │├────────────┼────────┤│ . │ 1204 │ lui-même│ .. │ 902 │ son parent│ rapport.md │ 3311 ││ copie.md │ 3311 │ ← le MÊME inode : deux noms, un seul contenu└────────────┴────────┘L'inode porte tout ce qu'on sait d'un fichier sauf son nom : taille, propriétaire, droits, dates, et les adresses des blocs de données. Le nom est dans le répertoire, pas dans l'inode — et c'est ce qui permet à deux entrées de désigner le même inode. C'est un lien physique, et l'inode compte ses références.
rm décrémente ce compteur et retire l'entrée du répertoire. Les blocs ne sont libérés que
lorsque le compteur atteint zéro et qu'aucun processus n'a le fichier ouvert. D'où le
comportement de l'introduction, et deux conséquences pratiques : la suppression ne détruit pas
les données, elle les rend seulement inaccessibles — ce qui fonde la récupération de fichiers et
justifie l'effacement sécurisé ; et un fichier volumineux ouvert par un processus continue
d'occuper le disque après un rm, ce qui explique bien des « disques pleins » où du ne trouve
rien.
Il faut distinguer le lien symbolique, qui est un fichier contenant un chemin. Il peut pointer sur un autre système de fichiers, mais il devient invalide si la cible disparaît, alors qu'un lien physique reste toujours valide.
Droits et propriétaires
Chaque fichier appartient à un utilisateur et à un groupe, et porte neuf bits de permission — trois catégories, trois droits :
-rwxr-xr-- 1 ana etudiants 4096 rapport.md │└┬┘└┬┘└┬┘ │ │ │ └── autres : r-- lecture seule │ │ └───── groupe : r-x lecture et exécution │ └──────── propriétaire : rwx └────────── type : - fichier, d répertoire, l lienL'écriture octale du chapitre 1 d'architecture prend ici tout son sens : chaque groupe de trois
bits est un chiffre octal, d'où chmod 754. Les valeurs se composent — 4 pour lire, 2 pour
écrire, 1 pour exécuter — et 755 ou 644 sont les deux motifs qu'on écrit sans réfléchir.
Le point qui trompe : sur un répertoire, les droits n'ont pas le même sens. r permet de
lister les noms, w d'y créer ou supprimer des entrées, et x de le traverser,
c'est-à-dire d'accéder à ce qu'il contient si l'on en connaît le nom. Un répertoire en r--
laisse voir les noms sans pouvoir ouvrir les fichiers ; en --x, il laisse ouvrir un fichier
dont on connaît le chemin exact sans pouvoir découvrir la liste. Et surtout, supprimer un
fichier ne demande aucun droit sur le fichier : c'est une modification du répertoire, donc
seul w sur le répertoire compte. Un fichier en lecture seule dans un répertoire où vous
écrivez est effaçable par vous.
Sur le disque : blocs et allocation
Le disque est découpé en blocs de taille fixe, typiquement 4 Kio — la même que la page du chapitre 6, et ce n'est pas un hasard. Reste à savoir quels blocs appartiennent à quel fichier, et trois réponses ont été essayées.
L'allocation contiguë met le fichier dans des blocs consécutifs. Lecture séquentielle très rapide, accès direct immédiat — et exactement la fragmentation externe du chapitre 6, plus l'impossibilité d'agrandir un fichier coincé entre deux voisins. On ne la trouve plus que sur les supports en lecture seule, comme les disques optiques.
L'allocation chaînée met dans chaque bloc l'adresse du suivant. Plus de fragmentation, mais l'accès direct devient impossible : atteindre le millième bloc demande de lire les 999 premiers. La variante FAT sort les pointeurs des blocs et les met dans une table unique, chargée en mémoire : l'accès direct redevient possible en parcourant la table plutôt que le disque. C'est l'organisation des clés USB et des cartes mémoire, et sa limite est que la table doit tenir en mémoire, donc grandit avec le disque.
L'allocation indexée est celle d'Unix. Chaque fichier a un inode qui contient un tableau d'adresses de blocs. L'accès direct est immédiat, il n'y a pas de fragmentation externe — et le tableau est de taille fixe, ce qui poserait une limite si l'on s'arrêtait là.
Les blocs indirects
La solution est élégante et se retrouve dans presque tous les systèmes de fichiers modernes. L'inode contient :
12 pointeurs DIRECTS → 12 blocs de données 1 pointeur INDIRECT SIMPLE → un bloc rempli de pointeurs 1 pointeur INDIRECT DOUBLE → un bloc de pointeurs vers des blocs de pointeurs 1 pointeur INDIRECT TRIPLE → un niveau de plusAvec des blocs de 4 Kio et des pointeurs de 4 octets, un bloc contient 1024 pointeurs. La capacité totale se calcule alors ainsi :
direct 12 × 4 Kio = 48 Kioindirect simple 1024 × 4 Kio = 4 Mioindirect double 1024 × 1024 × 4 Kio = 4 Gioindirect triple 1024 × 1024 × 1024 × 4 Kio = 4 TioL'intérêt de cette structure asymétrique est qu'elle s'adapte à la distribution réelle des tailles de fichiers. L'immense majorité des fichiers font moins de 48 Kio : leur inode suffit, et un accès demande une seule lecture. Les gros fichiers, rares, paient un ou deux accès supplémentaires — ce qui est acceptable puisqu'ils sont rares, et que le cache du système gardera de toute façon leurs blocs d'index.
Quiz · 1 question
Un utilisateur ne peut pas modifier un fichier appartenant à quelqu'un d'autre, mais il parvient à le supprimer. Comment est-ce possible ?
- C'est un bogue du système de fichiers : supprimer devrait exiger le droit d'écriture sur le fichier — bogue
- Supprimer un fichier, c'est retirer une entrée d'un RÉPERTOIRE : seul le droit d'écriture sur le répertoire est requis, les droits du fichier n'entrent pas en jeu — l'entrée est dans le répertoire
- L'utilisateur appartient au groupe propriétaire du fichier — appartenance au groupe
Réponse : C'est la conséquence directe de la séparation entre le nom et le contenu. Le nom vit dans le répertoire, sous forme d'un couple (nom, numéro d'inode) ; les droits vivent dans l'inode. Supprimer, c'est retirer le couple du répertoire et décrémenter le compteur de références de l'inode : une modification du répertoire, qui ne demande que le droit w sur celui-ci. Un fichier en lecture seule placé dans un répertoire où vous écrivez est donc effaçable par vous — comportement qui surprend systématiquement, et qui explique le bit « sticky » posé sur /tmp, lequel restreint justement la suppression au propriétaire du fichier.
Le montage
Le chapitre 2 l'a annoncé : Unix n'a qu'un seul arbre. Le montage est l'opération qui greffe le système de fichiers d'un périphérique sur un répertoire existant, appelé point de montage.
mount /dev/sdb1 /media/cleAprès quoi /media/cle/photo.jpg désigne un fichier de la clé, atteint par les mêmes appels
système et les mêmes commandes que n'importe quel autre. Le contenu que le point de montage
avait avant l'opération est masqué tant que le montage dure — il n'est pas détruit, mais il
n'est plus atteignable.
C'est l'abstraction du chapitre 1 poussée à son terme : la table de montage, plus une couche
appelée système de fichiers virtuel qui définit une interface commune, permettent à ext4, à
NTFS, à un partage réseau et à /proc de coexister sous les mêmes commandes. Un programme qui
lit un fichier ne sait pas — et n'a pas besoin de savoir — sur quel type de support il se
trouve.
La journalisation
Une opération apparemment simple — créer un fichier — modifie plusieurs structures : l'inode, la table des blocs libres, l'entrée de répertoire. Une coupure de courant au milieu laisse un système incohérent : un bloc marqué occupé qu'aucun inode ne réclame, ou pire, un inode pointant vers un bloc réattribué à un autre fichier.
L'ancienne parade était de tout vérifier au démarrage — un parcours complet du disque, qui prenait des heures sur un gros volume.
La journalisation procède autrement : avant de modifier quoi que ce soit, le système écrit dans un journal ce qu'il s'apprête à faire, puis exécute, puis efface l'entrée du journal. Après une coupure, il suffit de relire le journal et de rejouer ou d'annuler les opérations inachevées — quelques secondes au lieu de quelques heures.
La plupart des systèmes ne journalisent que les métadonnées, pas les données. C'est un compromis explicite : la structure est garantie cohérente, mais un fichier peut se retrouver avec des blocs au contenu indéterminé. Journaliser aussi les données double les écritures.
Quiz · 1 question
Avec des blocs de 4 Kio et des pointeurs de 4 octets, quelle taille maximale un fichier peut-il atteindre en n'utilisant que les 12 pointeurs directs et l'indirect simple ?
- 48 Kio + 4 Mio, car le bloc indirect contient 4096/4 = 1024 pointeurs vers des blocs de 4 Kio — 1024 pointeurs
- 48 Kio + 4 Kio, car l'indirect simple ajoute un seul bloc de données — un bloc de plus
- 16 × 4 Kio = 64 Kio, car l'inode contient 16 pointeurs au total — 16 pointeurs
Réponse : Le raisonnement se fait en deux temps. Combien de pointeurs tiennent dans un bloc ? 4096 octets ÷ 4 octets par pointeur = 1024. Ce bloc indirect ne contient AUCUNE donnée : il ne contient que des adresses, qui désignent 1024 blocs de données, soit 1024 × 4 Kio = 4 Mio. Les 12 pointeurs directs, eux, désignent directement 12 × 4 Kio = 48 Kio. Total : 4 Mio et 48 Kio. La deuxième réponse est l'erreur classique — confondre le bloc d'index et un bloc de données. La troisième oublie que les trois derniers pointeurs de l'inode ne sont pas de même nature que les douze premiers.
À vous
L'exercice est le calcul d'examen du chapitre, écrit une fois pour toutes. Vous implémentez la résolution d'un déplacement en octets vers un numéro de bloc à travers la structure de l'inode : direct, indirect simple, indirect double — en comptant au passage combien d'accès disque la résolution a coûté.
C'est ce compteur qui rend la structure compréhensible. On voit que les premiers 48 Kio coûtent un accès, que le mégaoctet suivant en coûte deux, et pourquoi c'est le bon compromis compte tenu de la distribution réelle des tailles de fichiers.
Exercice de code
Résolvez un déplacement en octets à travers l'inode, et comptez les accès disque.
Point de départ
const BLOC = 4096; // 4 Kio
const POINTEUR = 4; // 4 octets par adresse
const PAR_BLOC = BLOC / POINTEUR; // 1024 pointeurs dans un bloc d'index
const DIRECTS = 12;
// Capacités cumulées, en blocs de données.
const CAP_DIRECT = DIRECTS; // 12
const CAP_SIMPLE = PAR_BLOC; // 1024
const CAP_DOUBLE = PAR_BLOC * PAR_BLOC; // 1 048 576
// Résout un déplacement en octets vers un bloc logique, en disant par où l'on
// est passé et combien d'accès disque cela a coûté.
function resoudre(octet) {
const blocLogique = Math.floor(octet / BLOC);
const dansLeBloc = octet % BLOC;
if (blocLogique < CAP_DIRECT) {
return { voie: "direct", indices: [blocLogique], dansLeBloc, acces: 1 };
}
let reste = blocLogique - CAP_DIRECT;
if (reste < CAP_SIMPLE) {
// Un accès pour lire le bloc d'index, un pour la donnée.
return { voie: "indirect simple", indices: [reste], dansLeBloc, acces: 2 };
}
reste -= CAP_SIMPLE;
if (reste < CAP_DOUBLE) {
return null; // ← à écrire : indirect double
}
return { erreur: "au-delà de l'indirect double" };
}
// ── À VOUS ────────────────────────────────────────────────────────────────
// 1. Complétez la branche « indirect double » : deux indices (quel bloc du
// premier niveau, quelle entrée dedans) et le bon nombre d'accès.
// 2. Écrivez tailleMax(), qui rend la taille maximale d'un fichier avec
// directs + simple + double.
// 3. Vérifiez qu'un fichier de moins de 48 Kio coûte toujours UN accès.
function tailleMax() {
return 0; // ← à écrire
}
const CAS = [0, 40000, 49152, 60000, 4 * 1024 * 1024, 100 * 1024 * 1024];
for (const o of CAS) {
const r = resoudre(o);
console.log(String(o).padStart(10) + " octets -> " +
(r === null ? "à écrire" : r.erreur ?? (r.voie.padEnd(16) + " indices " +
JSON.stringify(r.indices).padEnd(16) + " " + r.acces + " accès disque")));
}
console.log("taille maximale :", tailleMax(), "octets");
Solution
const BLOC = 4096;
const POINTEUR = 4;
const PAR_BLOC = BLOC / POINTEUR;
const DIRECTS = 12;
const CAP_DIRECT = DIRECTS;
const CAP_SIMPLE = PAR_BLOC;
const CAP_DOUBLE = PAR_BLOC * PAR_BLOC;
function resoudre(octet) {
const blocLogique = Math.floor(octet / BLOC);
const dansLeBloc = octet % BLOC;
if (blocLogique < CAP_DIRECT) {
return { voie: "direct", indices: [blocLogique], dansLeBloc, acces: 1 };
}
let reste = blocLogique - CAP_DIRECT;
if (reste < CAP_SIMPLE) {
return { voie: "indirect simple", indices: [reste], dansLeBloc, acces: 2 };
}
reste -= CAP_SIMPLE;
if (reste < CAP_DOUBLE) {
// Deux niveaux d'index : le quotient désigne l'entrée du premier bloc
// d'index, le reste désigne l'entrée du bloc de second niveau. Trois
// accès disque : index 1, index 2, donnée.
const premier = Math.floor(reste / PAR_BLOC);
const second = reste % PAR_BLOC;
return { voie: "indirect double", indices: [premier, second], dansLeBloc, acces: 3 };
}
return { erreur: "au-delà de l'indirect double" };
}
function tailleMax() {
return (CAP_DIRECT + CAP_SIMPLE + CAP_DOUBLE) * BLOC;
}
const CAS = [0, 40000, 49152, 60000, 4 * 1024 * 1024, 100 * 1024 * 1024];
for (const o of CAS) {
const r = resoudre(o);
console.log(String(o).padStart(10) + " octets -> " +
(r.erreur ?? (r.voie.padEnd(16) + " indices " +
JSON.stringify(r.indices).padEnd(16) + " " + r.acces + " accès disque")));
}
const max = tailleMax();
console.log("");
console.log("taille maximale : " + max + " octets = " +
(max / (1024 * 1024 * 1024)).toFixed(2) + " Gio");
// Combien d'accès selon la taille du fichier ?
console.log("");
console.log("— coût d'un accès selon la position —");
for (const [nom, o] of [["fichier de 10 Kio", 10 * 1024],
["fichier de 40 Kio", 40 * 1024],
["dernier octet des directs", 48 * 1024 - 1],
["premier octet au-delà", 48 * 1024],
["à 3 Mio", 3 * 1024 * 1024],
["à 50 Mio", 50 * 1024 * 1024]]) {
console.log(" " + nom.padEnd(28) + resoudre(o).acces + " accès");
}
// La marche se voit nettement à 48 Kio. C'est là que se justifie la
// structure asymétrique : l'immense majorité des fichiers d'un système
// tiennent sous cette barre et se lisent en un seul accès, tandis que les
// gros fichiers, rares, paient deux ou trois accès — dont les blocs d'index
// resteront de toute façon dans le cache du système.
En travaux pratiques
Travaux pratiques 7 · 3 h
Un fichier n'est pas son nom
Séparer le nom, l'inode et le contenu — la distinction qui explique les liens, la suppression, l'espace qui ne se libère pas, et la récupération d'un fichier effacé.
Avant de commencer
- Les TP 2 et 3
- Les commandes ls -i, stat, lsof, df, du
Énoncé
- Voir l'inode — Créez un fichier, affichez son inode et ses métadonnées. Listez ce qui est stocké dans l'inode et ce qui ne l'est pas. Où est le nom ?
- Deux noms, un fichier — Créez un lien dur vers ce fichier. Comparez les inodes, modifiez par un nom, lisez par l'autre. Supprimez le premier nom : que devient le contenu ?
- Le lien symbolique — Créez un lien symbolique vers le même fichier et refaites les mêmes essais. Supprimez la cible et observez. Établissez le tableau des différences.
- L'espace qui ne revient pas — Créez un fichier d'un gigaoctet, ouvrez-le depuis un programme qui dort, supprimez-le pendant ce temps. Comparez ce que disent df et du. Expliquez. Indice : Le contenu disparaît quand le dernier NOM et le dernier DESCRIPTEUR ont disparu.
- Récupérer l'irrécupérable — Sans arrêter le programme précédent, retrouvez le contenu du fichier supprimé en passant par /proc. Vous venez de récupérer un fichier effacé.
- Épuiser autre chose que l'espace — Sur une petite partition de test, créez des centaines de milliers de fichiers vides jusqu'à l'échec. Regardez df puis df -i, et expliquez le message.
- Écriture atomique — Écrivez un programme qui remplace un fichier de configuration, et tuez-le au milieu de l'écriture. Constatez la corruption, puis réécrivez-le avec le motif écrire-puis-renommer et refaites l'essai.
C'est réussi quand
- Vous savez dire où est stocké le nom d'un fichier, et ce n'est pas dans l'inode
- Vous récupérez le contenu d'un fichier supprimé encore ouvert
- Le disque est plein alors que df annonce de la place, et vous savez pourquoi
- Votre configuration n'est jamais corrompue, même tuée en pleine écriture
Correction
stat essai.txt
Inode: 1179654 Links: 1
Access: (0644/-rw-r--r--) Uid: 1000 Gid: 1000
Size: 12 Blocks: 8
Modify: 2026-09-07 10:14:02
dans l'inode : type, droits, propriétaire, tailles, dates,
pointeurs vers les blocs de données
PAS dans l'inode : le NOMLe nom est dans le RÉPERTOIRE, qui n'est qu'une table associant des noms à des numéros d'inode. Un répertoire ne contient donc pas les fichiers : il contient leurs noms. Toute la suite du TP découle de cette seule séparation.
lien dur lien symbolique même inode ? oui non (inode propre) cible supprimée contenu intact lien CASSÉ entre partitions impossible possible sur un répertoire interdit autorisé contenu du lien — un CHEMIN, en texte ls -i 1179654 essai.txt 1179654 copie.txt ← même inode 1179654 essai.txt 1179701 raccourci ← inodes différents
Un lien dur n'est pas une copie ni un raccourci : c'est un SECOND NOM, exactement au même titre que le premier. Il n'y a pas d'original. Le lien symbolique, lui, est un petit fichier contenant un chemin — d'où sa fragilité, et d'où sa capacité à traverser les partitions, qu'un lien dur n'a pas puisque les numéros d'inode sont locaux à un système de fichiers.
du → 0 (plus aucun NOM dans aucun répertoire) df → 1 Go pris (le contenu existe toujours) un inode est libéré quand : nombre de liens == 0 ET nombre de descripteurs ouverts == 0 /* d'où le grand classique : */ rm /var/log/enorme.log sans redémarrer le service qui l'écrit → l'espace n'est PAS rendu. Il faut fermer le fichier (ou tronquer : > /var/log/enorme.log)
C'est l'incident de production le plus banal qui soit : un disque plein, un gros journal supprimé, et rien qui ne se libère. La commande lsof avec l'option +L1 liste précisément ces fichiers sans nom mais encore ouverts. Corollaire : la vraie suppression, c'est unlink — « retirer un nom » — et le nom de l'appel système le dit.
lsof +L1 → pid 4217, descripteur 3 cp /proc/4217/fd/3 recupere.txt /* /proc/PID/fd/N est un lien vers l'inode ouvert : tant que le processus vit, le contenu est accessible */
Le fichier n'avait plus de nom ; il en a un de nouveau. Cela vaut pour un journal supprimé par erreur comme pour une analyse après incident — et c'est aussi une raison de ne pas croire qu'un rm efface quoi que ce soit. Effacer réellement demande d'écraser, et sur un disque à mémoire flash même cela ne suffit pas, à cause de la répartition d'usure.
touch: cannot touch 'f200000': No space left on device df → 62 % utilisé ← il reste de la place ! df -i → 100 % d'inodes utilisés le nombre d'inodes est FIXÉ à la création du système de fichiers
Deux ressources indépendantes s'épuisent : les blocs de données et les inodes. Des millions de petits fichiers — un cache, des sessions, des courriels — épuisent les seconds bien avant les premiers. Le message d'erreur, lui, est le même dans les deux cas, ce qui rend le diagnostic déroutant si l'on ne connaît pas l'option -i.
/* NON atomique : une fenêtre de corruption */
fd = open("config.conf", O_WRONLY|O_TRUNC); ← le fichier est vidé ICI
write(fd, contenu, taille); ← tué ici = fichier vide
close(fd);
/* atomique */
fd = open("config.conf.tmp", O_WRONLY|O_CREAT, 0644);
write(fd, contenu, taille);
fsync(fd); /* les données sont sur le disque */
close(fd);
rename("config.conf.tmp", "config.conf"); /* ATOMIQUE */rename est garanti atomique par le système : à tout instant, un lecteur voit soit l'ancien fichier complet, soit le nouveau, jamais un intermédiaire. Le fsync avant est indispensable — sans lui, le renommage peut être enregistré avant les données, et une coupure laisse un fichier vide portant le bon nom. C'est ainsi qu'écrivent les éditeurs, les gestionnaires de paquets et les bases de données.
Ce que la suite en fait
Le chapitre 8 termine le cours en descendant sous le système de fichiers : les pilotes qui parlent au contrôleur, les tampons qui absorbent l'écart de vitesse, et l'ordonnancement des requêtes disque — car les blocs que ce chapitre a numérotés se trouvent physiquement quelque part, et l'ordre dans lequel on les demande change le temps total.
Les droits posés ici y reviendront aussi, du côté sécurité : ce sont eux qui portent l'isolation entre utilisateurs, et le chapitre montrera par quels mécanismes on va au-delà.
À retenir
Flashcards · 5 cartes
- Qu'est-ce qu'un inode, et pourquoi rm n'efface-t-il rien ?
- L'inode porte tout ce qu'on sait d'un fichier SAUF son nom : taille, propriétaire, droits, dates, adresses des blocs. Le nom vit dans le répertoire, sous forme d'un couple (nom, numéro d'inode) — d'où la possibilité que deux noms désignent le même inode (lien physique). rm retire une entrée de répertoire et décrémente le compteur de références ; les blocs ne sont libérés qu'à zéro ET si aucun processus n'a le fichier ouvert.
- Que signifient r, w et x sur un RÉPERTOIRE ?
- r : lister les noms qu'il contient. w : y créer ou supprimer des entrées. x : le traverser, donc atteindre ce qu'il contient si l'on en connaît le nom. Conséquence majeure : supprimer un fichier ne demande AUCUN droit sur le fichier, seulement w sur le répertoire — un fichier en lecture seule dans un répertoire où vous écrivez est effaçable par vous. C'est ce que corrige le bit sticky sur /tmp.
- Comparez allocation contiguë, chaînée et indexée.
- CONTIGUË : blocs consécutifs, très rapide en séquentiel et en accès direct, mais fragmentation externe et impossibilité d'agrandir — réservée aux supports en lecture seule. CHAÎNÉE : chaque bloc pointe le suivant, pas de fragmentation mais aucun accès direct ; la variante FAT sort les pointeurs dans une table en mémoire, qui doit tenir en RAM. INDEXÉE (Unix) : un inode contient le tableau des adresses, accès direct immédiat et pas de fragmentation externe.
- Comment un inode dépasse-t-il la limite de son tableau de pointeurs ?
- Par les blocs INDIRECTS : 12 pointeurs directs, puis un indirect simple (un bloc rempli de pointeurs), un indirect double (un bloc de pointeurs vers des blocs de pointeurs), un indirect triple. Avec des blocs de 4 Kio et des pointeurs de 4 octets — donc 1024 pointeurs par bloc — cela donne 48 Kio, puis 4 Mio, puis 4 Gio, puis 4 Tio. La structure est asymétrique parce que la distribution des tailles de fichiers l'est : les petits fichiers, majoritaires, coûtent un seul accès.
- Qu'apporte la journalisation, et que journalise-t-on en pratique ?
- Créer un fichier modifie plusieurs structures (inode, table des blocs libres, entrée de répertoire) ; une coupure au milieu laisse un système incohérent, qu'il fallait autrefois vérifier en parcourant tout le disque. La journalisation écrit d'abord dans un journal ce qu'elle va faire, exécute, puis efface l'entrée : après une coupure, on rejoue ou annule les opérations inachevées en quelques secondes. En pratique on ne journalise que les MÉTADONNÉES — la structure est cohérente, mais le contenu d'un fichier peut rester indéterminé.