Système de Fichiers
Un système de fichiers (filesystem) est la structure logique qui organise et gère le stockage des données sur un support physique. Il fournit une abstraction permettant d’accéder aux données via des noms lisibles plutôt que des adresses de blocs physiques.
VFS — Virtual File System§
Linux utilise une couche d’abstraction appelée VFS qui offre une interface uniforme (open, read, write, close) quel que soit le système de fichiers concret (ext4, Btrfs, FAT32, tmpfs, proc…).
Application
│ open("/home/alice/doc.txt", ...)
▼
VFS (couche d'abstraction)
│
├── ext4 (disque local)
├── tmpfs (RAM)
├── proc (pseudo-FS pour les informations noyau)
├── NFS (réseau)
└── FUSE (filesystems en espace utilisateur)
Structures internes (ext4)§
Inode§
Structure de données représentant un fichier ou répertoire. Chaque inode contient les métadonnées mais pas le nom du fichier.
Inode #1042 :
Type : fichier régulier
Permissions : rw-r--r-- (644)
Propriétaire : uid=1000, gid=1000
Taille : 4096 octets
Blocs : [2048, 2049, 2050] (pointeurs vers les blocs de données)
Nombre liens : 1
atime : 2025-01-15 10:30:00 (dernier accès)
mtime : 2025-01-10 14:22:33 (dernière modification)
ctime : 2025-01-10 14:22:33 (dernier changement de métadonnées)
L’inode stocke des pointeurs directs vers les blocs de données, des pointeurs indirects (un bloc contenant des pointeurs), doublement indirects et triplement indirects pour les très gros fichiers.
Blocs§
La mémoire disque est divisée en blocs (typiquement 4 Ko). Un fichier peut occuper plusieurs blocs, pas forcément contigus.
Répertoires§
Un répertoire est un fichier spécial qui contient une liste d’entrées : chaque entrée associe un nom de fichier à un numéro d’inode.
Contenu de /home/alice/ :
. → inode #1040 (répertoire courant)
.. → inode #38 (répertoire parent)
doc.txt → inode #1042
images → inode #1055 (répertoire)
.bashrc → inode #1041
Le nom du fichier est stocké dans le répertoire, pas dans l’inode. C’est pourquoi mv dans le même filesystem est instantané (on change juste l’entrée dans le répertoire).
Liens symboliques vs liens durs§
Lien dur (hard link)§
Crée une nouvelle entrée de répertoire pointant vers le même inode. Le fichier n’est supprimé que quand le compteur de liens tombe à 0.
ln fichier.txt lien_dur.txt
# Les deux entrées pointent vers le même inode
ls -li fichier.txt lien_dur.txt # même numéro d'inode
stat fichier.txt # Nlinks: 2
rm fichier.txt # Nlinks: 1 — les données sont conservées
rm lien_dur.txt # Nlinks: 0 — les données sont supprimées
Limitations : impossible de créer des liens durs entre filesystems différents, ni vers des répertoires (pour éviter les cycles).
Lien symbolique (symbolic link / symlink)§
Fichier spécial contenant le chemin vers la cible. Suit les déplacements si le chemin reste valide.
ln -s /home/alice/documents docs_alice
# docs_alice contient la chaîne "/home/alice/documents"
# Si alice déplace documents, le lien est cassé (dangling symlink)
ls -la docs_alice # docs_alice -> /home/alice/documents
| Critère | Lien dur | Lien symbolique |
|---|---|---|
| Cross-filesystem | Non | Oui |
| Vers répertoires | Non | Oui |
| Si cible déplacée | Toujours valide | Peut se casser |
| Espace occupé | Aucun (juste une entrée) | Quelques octets |
| Accès aux métadonnées | Inode de la cible | Inode propre |
Systèmes de fichiers courants§
| Filesystem | OS | Journalisation | Taille max fichier | Points forts |
|---|---|---|---|---|
| ext4 | Linux | Oui | 16 To | Stable, universel, bien supporté |
| Btrfs | Linux | Oui (COW) | 16 Eio | Snapshots, checksums, RAID intégré |
| XFS | Linux | Oui | 8 Eio | Performances en écriture, grands fichiers |
| ZFS | Linux/BSD | Oui (COW) | 16 Eio | Intégrité maximale, déduplication |
| NTFS | Windows | Oui | 256 To | Standard Windows, permissions avancées |
| FAT32 | Universel | Non | 4 Go | Compatibilité maximale (clés USB) |
| exFAT | Universel | Non | 128 Po | FAT32 moderne, grosses clés USB, SD |
| APFS | macOS/iOS | Oui (COW) | 8 Eio | Chiffrement natif, snapshots, Clone |
Journalisation§
La journalisation protège contre la corruption lors d’une coupure de courant. Avant de modifier les données, le filesystem écrit l’opération dans un journal (log). Après une panne, le journal est relu pour compléter ou annuler les opérations incomplètes.
Write-ahead logging : le journal enregistre ce qui va être fait avant que ça soit fait.
Copy-On-Write (COW) : plutôt qu’écrire sur place, écrire dans de nouveaux blocs et mettre à jour les pointeurs atomiquement. Btrfs, ZFS et APFS utilisent COW → les données originales restent valides jusqu’à la transaction complète.
Permissions Unix§
Mode de base (rwx)§
-rw-r--r-- 1 alice users 4096 Jan 15 10:30 fichier.txt
│└─┬──┘└─┬──┘└─┬──┘
│ │ │ └── Autres (others) : r-- = lecture seulement
│ │ └── Groupe (group) : r-- = lecture seulement
│ └── Propriétaire (owner) : rw- = lecture + écriture
└── Type : - fichier, d répertoire, l lien symb., p pipe, c char device
r = 4, w = 2, x = 1
rw-r--r-- = 644
rwxr-xr-x = 755
chmod 755 script.sh # notation octale
chmod u+x,g-w,o=r fichier # notation symbolique
chmod -R 644 repertoire/ # récursif
chown alice:developers fichier.txt # changer propriétaire et groupe
chgrp developers fichier.txt # changer seulement le groupe
Permissions spéciales§
SetUID (4xxx) : quand un exécutable a le bit SetUID, il s’exécute avec les permissions de son propriétaire (ex: passwd s’exécute en root pour modifier /etc/shadow).
chmod 4755 executable # ou chmod u+s executable
ls -la executable # -rwsr-xr-x (s = setuid)
SetGID (2xxx) : exécutable avec les permissions du groupe. Sur un répertoire : les fichiers créés héritent du groupe du répertoire.
Sticky bit (1xxx) : sur un répertoire, seul le propriétaire peut supprimer/renommer ses propres fichiers (même si le répertoire est accessible en écriture par tous). Utilisé sur /tmp.
ls -la /tmp # drwxrwxrwt (t = sticky bit)
ACL — Access Control Lists§
Permissions plus granulaires que les trois catégories owner/group/others.
# Donner accès en lecture à bob sans changer le groupe
setfacl -m u:bob:r-- fichier.txt
getfacl fichier.txt
# Donner accès en écriture au groupe "devops"
setfacl -m g:devops:rw- repertoire/
# ACL par défaut pour les fichiers créés dans un répertoire
setfacl -d -m u:bob:r-- repertoire/
Montage et démontage§
# Monter un filesystem
mount /dev/sdb1 /mnt/data
mount -t ext4 /dev/sdb1 /mnt/data # type explicite
mount -o ro /dev/sdb1 /mnt/data # lecture seule
mount -o remount,rw /mnt/data # remonter en lecture-écriture
# Configuration permanente dans /etc/fstab
# <dispositif> <point_montage> <type> <options> <dump> <pass>
/dev/sda1 / ext4 defaults 0 1
/dev/sda2 /home ext4 defaults 0 2
UUID=abc123 /data xfs defaults,noatime 0 2
tmpfs /tmp tmpfs size=2G 0 0
# Démontage (nécessite qu'aucun processus n'utilise le filesystem)
umount /mnt/data
umount -l /mnt/data # lazy unmount — détache le filesystem dès que possible
# Identifier le processus bloquant
lsof /mnt/data
fuser /mnt/data
Opérations fichiers au niveau syscall§
import os
# open() — retourne un descripteur de fichier (entier)
fd = os.open("fichier.txt", os.O_RDWR | os.O_CREAT, 0o644)
# read(), write()
data = os.read(fd, 4096) # lire jusqu'à 4096 octets
os.write(fd, b"nouveau contenu")
# lseek() — déplacer la position
os.lseek(fd, 0, os.SEEK_SET) # retour au début
os.lseek(fd, 0, os.SEEK_END) # fin du fichier
os.lseek(fd, -100, os.SEEK_CUR) # 100 octets en arrière
# close() — libère le descripteur
os.close(fd)
# Descripteurs standard : 0=stdin, 1=stdout, 2=stderr
Commandes de diagnostic§
df -h # Espace disque par partition
du -sh * # Taille de chaque entrée du répertoire courant
du -sh /var/log --max-depth=1
find / -size +100M 2>/dev/null # Fichiers > 100 Mo
lsof +D /mnt/data # Fichiers ouverts dans un répertoire
stat fichier.txt # Métadonnées détaillées
file document # Déterminer le type d'un fichier
inotifywait -m /tmp # Surveiller les événements filesystem