Systèmes de fichiers sous Linux

Ce forum est dédié à apprendre le développement de programmes user mode sur Linux

Moderator: Rick

Post Reply
Hydraxx
Site Admin
Posts: 46
Joined: Mon Jan 12, 2026 4:04 pm
Location: France
Contact:

Systèmes de fichiers sous Linux

Post by Hydraxx »

Systèmes de fichiers sous Linux

Introduction

Sous Linux, un fichier n’est pas seulement un nom avec du contenu. Derrière chaque fichier, il existe une organisation beaucoup plus profonde : périphériques, partitions, systèmes de fichiers, inodes, blocs de données, points de montage, VFS, options de montage, etc.

Ce chapitre explique comment Linux organise les fichiers sur disque et comment il donne à l’utilisateur une vision simple :

Code: Select all

/
├── bin
├── boot
├── dev
├── etc
├── home
├── proc
├── sys
├── tmp
└── usr
Mais derrière cette arborescence unique, plusieurs systèmes de fichiers peuvent être montés :
  • ext4 sur la partition principale ;
  • tmpfs pour certains répertoires temporaires ;
  • procfs pour exposer des informations du noyau ;
  • sysfs pour exposer des informations sur les périphériques ;
  • vfat, ntfs, iso9660, nfs, etc.
L’idée centrale du chapitre est donc :

Code: Select all

Programme utilisateur
        |
        v
open(), read(), write(), stat(), mkdir(), unlink()
        |
        v
VFS : Virtual File System
        |
        +--> ext4
        +--> xfs
        +--> btrfs
        +--> tmpfs
        +--> procfs
        +--> sysfs
        +--> nfs
        +--> vfat
        +--> ntfs
Grâce au VFS, un programme peut utiliser les mêmes appels système sans forcément connaître le système de fichiers réel utilisé derrière.

1. Les fichiers spéciaux de périphériques

Sous Linux, beaucoup de périphériques sont visibles sous forme de fichiers spéciaux dans le répertoire :

Code: Select all

/dev
Exemples :

Code: Select all

/dev/sda
/dev/sda1
/dev/null
/dev/zero
/dev/tty
/dev/random
/dev/urandom
Ces fichiers ne sont pas des fichiers ordinaires. Ils représentent une interface vers un périphérique ou vers un comportement fourni par le noyau.

Il existe deux grandes familles :
  • block devices : périphériques à blocs ;
  • character devices : périphériques caractère.
1.1. Périphérique bloc

Un périphérique bloc fonctionne par blocs. C’est typiquement le cas des périphériques de stockage.

Exemples :

Code: Select all

/dev/sda
/dev/sda1
/dev/nvme0n1
/dev/nvme0n1p1
Un disque dur, un SSD, une clé USB ou une carte SD sont des périphériques bloc.

Le noyau peut lire ou écrire des blocs de données sur ces périphériques. Ensuite, au-dessus de ces blocs, on peut installer un système de fichiers comme ext4, xfs, btrfs, vfat, etc.

1.2. Périphérique caractère

Un périphérique caractère fonctionne plutôt comme un flux d’octets.

Exemples :

Code: Select all

/dev/tty
/dev/null
/dev/zero
/dev/random
/dev/urandom
Un périphérique caractère n’est pas manipulé comme un disque découpé en blocs. On lit ou écrit des octets dans un flux.

1.3. Major number et minor number

Chaque fichier spécial de périphérique est associé à deux numéros :
  • major number ;
  • minor number.
Le major number indique généralement quel pilote gère le périphérique.

Le minor number identifie une instance particulière gérée par ce pilote.

Schéma mental :

Code: Select all

major number = quel driver ?
minor number = quelle instance précise ?
Exemple conceptuel :

Code: Select all

/dev/sda   -> disque entier
/dev/sda1  -> première partition
/dev/sda2  -> deuxième partition
Le noyau utilise ces informations pour rediriger les opérations de lecture et d’écriture vers le bon pilote.

2. Disques et partitions

Un disque physique peut être divisé en plusieurs partitions.

Exemple :

Code: Select all

/dev/sda    -> disque entier
/dev/sda1   -> première partition
/dev/sda2   -> deuxième partition
/dev/sda3   -> troisième partition
Avec un disque NVMe, les noms sont souvent différents :

Code: Select all

/dev/nvme0n1      -> disque NVMe entier
/dev/nvme0n1p1    -> première partition
/dev/nvme0n1p2    -> deuxième partition
Une partition peut contenir :
  • un système de fichiers ;
  • de l’espace swap ;
  • des données brutes ;
  • une partition EFI ;
  • une partition utilisée par un autre système d’exploitation.
Exemple :

Code: Select all

/dev/sda1 -> ext4
/dev/sda2 -> swap
/dev/sda3 -> vfat
/dev/sda4 -> ntfs
2.1. Partition brute et système de fichiers

Une partition seule ne suffit pas forcément pour stocker des fichiers de manière organisée.

Pour que Linux puisse voir des fichiers et des répertoires, il faut généralement créer un système de fichiers sur cette partition.

Exemple :

Code: Select all

mkfs.ext4 /dev/sdb1
Cela prépare la partition avec les structures internes nécessaires : superblock, table d’inodes, blocs de données, informations d’allocation, etc.

3. Qu’est-ce qu’un système de fichiers ?

Un système de fichiers définit comment les données sont organisées dans une partition ou dans une zone de stockage.

Il gère :
  • les fichiers ;
  • les répertoires ;
  • les métadonnées ;
  • les permissions ;
  • les propriétaires ;
  • les groupes ;
  • les timestamps ;
  • les liens physiques ;
  • les blocs libres ;
  • les blocs utilisés ;
  • les inodes libres ;
  • les inodes utilisés.
Linux supporte de nombreux systèmes de fichiers :
  • ext2 ;
  • ext3 ;
  • ext4 ;
  • xfs ;
  • btrfs ;
  • vfat ;
  • ntfs ;
  • iso9660 ;
  • tmpfs ;
  • procfs ;
  • sysfs ;
  • nfs.
Certains sont de vrais systèmes de fichiers sur disque. D’autres sont virtuels.

3.1. Systèmes de fichiers sur disque

Un système de fichiers sur disque stocke réellement ses données sur un périphérique de stockage.

Exemples :

Code: Select all

ext4
xfs
btrfs
vfat
ntfs
Ces systèmes persistent après redémarrage, car les données sont écrites sur disque.

3.2. Systèmes de fichiers virtuels

Certains systèmes de fichiers ne correspondent pas à des fichiers classiques stockés sur disque.

Exemples :

Code: Select all

/proc
/sys
/dev
/run
/dev/shm
Leur contenu est souvent généré dynamiquement par le noyau.

Exemple :

Code: Select all

cat /proc/cpuinfo
cat /proc/mounts
cat /proc/self/status
Tu lis un fichier, mais ce fichier est en réalité une interface vers des informations du noyau.

4. Structure classique d’un système de fichiers

Un système de fichiers classique contient plusieurs zones importantes :
  • boot block ;
  • superblock ;
  • inode table ;
  • data blocks.
Schéma simplifié :

Code: Select all

+-------------+
| Boot block  |
+-------------+
| Superblock  |
+-------------+
| Inode table |
+-------------+
| Data blocks |
+-------------+
4.1. Boot block

Le boot block peut contenir du code de démarrage.

Il est surtout important pour les partitions amorçables. Tous les systèmes de fichiers peuvent réserver une zone de ce type, même si elle n’est pas toujours utilisée directement par Linux.

4.2. Superblock

Le superblock contient les informations globales du système de fichiers.

Il peut contenir :
  • la taille du système de fichiers ;
  • la taille des blocs ;
  • le nombre total de blocs ;
  • le nombre de blocs libres ;
  • le nombre total d’inodes ;
  • le nombre d’inodes libres ;
  • l’état du système de fichiers ;
  • des informations de configuration internes.
Le superblock est une structure critique. Si le superblock est corrompu, le système de fichiers peut devenir difficile ou impossible à monter.

4.3. Table des inodes

La table des inodes contient les inodes du système de fichiers.

Chaque inode décrit un fichier, un répertoire, un lien symbolique ou un autre objet du système de fichiers.

Point essentiel :

Code: Select all

L’inode ne contient pas le nom du fichier.
Il contient les métadonnées et les informations permettant de retrouver les blocs de données.

4.4. Blocs de données

Les blocs de données contiennent le contenu réel des fichiers.

Exemple :

Code: Select all

Nom dans un répertoire -> numéro d’inode -> inode -> blocs de données
Le contenu du fichier n’est donc pas directement dans l’inode. L’inode indique où sont les blocs contenant ce contenu.

5. Les inodes

L’inode est l’une des notions les plus importantes du chapitre.

Un inode est une structure qui contient les informations essentielles sur un fichier, sauf son nom.

Un inode contient typiquement :
  • le type de fichier ;
  • les permissions ;
  • l’UID du propriétaire ;
  • le GID du groupe ;
  • la taille du fichier ;
  • le nombre de liens physiques ;
  • les timestamps ;
  • les pointeurs vers les blocs de données.
En simplifié :

Code: Select all

inode = carte d’identité technique du fichier
Mais attention :

Code: Select all

inode != contenu du fichier
inode != nom du fichier
L’inode contient les métadonnées et les adresses permettant de retrouver le contenu.

5.1. Où est stocké le nom du fichier ?

Le nom du fichier est stocké dans un répertoire.

Un répertoire est lui-même un fichier spécial qui contient des associations :

Code: Select all

nom -> numéro d’inode
Exemple :

Code: Select all

"test.txt" -> inode 12345
"main.c"   -> inode 12346
"docs"     -> inode 12347
Ensuite, l’inode donne les informations sur l’objet.

Donc quand tu ouvres :

Code: Select all

/home/jean/test.txt
Linux parcourt les répertoires :

Code: Select all

/        -> trouve "home"
/home    -> trouve "jean"
/home/jean -> trouve "test.txt"
/home/jean/test.txt -> numéro d’inode
Puis le noyau utilise l’inode pour accéder aux métadonnées et aux blocs de données.

5.2. Hard links et inodes

Comme le nom du fichier n’est pas dans l’inode, plusieurs noms peuvent pointer vers le même inode.

C’est le principe du hard link.

Exemple :

Code: Select all

ln fichier.txt autre_nom.txt
Après cette commande, les deux noms peuvent pointer vers le même inode.

Schéma :

Code: Select all

fichier.txt    -> inode 5000
autre_nom.txt  -> inode 5000
Les deux noms désignent le même fichier réel.

Le nombre de hard links est stocké dans l’inode.

5.3. Différence simple entre nom, inode et contenu

Il faut bien séparer trois niveaux :

Code: Select all

Nom du fichier :
    stocké dans un répertoire

Inode :
    métadonnées + pointeurs vers les blocs

Blocs de données :
    contenu réel du fichier
Exemple mental :

Code: Select all

/home/jean/cours.txt
        |
        v
entrée de répertoire : "cours.txt" -> inode 9123
        |
        v
inode 9123 : taille, permissions, propriétaire, blocs
        |
        v
blocs de données : contenu texte du fichier
6. Organisation des blocs dans ext2

Dans un système comme ext2, l’inode contient des pointeurs vers les blocs de données.

Pour les petits fichiers, il peut utiliser des pointeurs directs.

Pour les gros fichiers, il utilise des niveaux d’indirection.

On trouve généralement :
  • des pointeurs directs ;
  • un pointeur indirect ;
  • un pointeur double indirect ;
  • un pointeur triple indirect.
Schéma simplifié :

Code: Select all

inode
 ├── pointeur direct        -> bloc de données
 ├── pointeur direct        -> bloc de données
 ├── pointeur direct        -> bloc de données
 ├── pointeur indirect      -> bloc contenant des pointeurs vers des blocs
 ├── pointeur double indirect
 └── pointeur triple indirect
6.1. Pourquoi utiliser des pointeurs indirects ?

Les petits fichiers doivent être rapides à accéder.

Pour eux, les pointeurs directs suffisent.

Mais un gros fichier peut contenir énormément de blocs. L’inode ne peut pas contenir directement des millions de pointeurs.

On utilise donc des blocs intermédiaires qui contiennent eux-mêmes des pointeurs.

Schéma :

Code: Select all

inode
  |
  +--> bloc indirect
          |
          +--> pointeur vers bloc de données
          +--> pointeur vers bloc de données
          +--> pointeur vers bloc de données
Avec double indirection :

Code: Select all

inode
  |
  +--> bloc double indirect
          |
          +--> bloc indirect
                  |
                  +--> bloc de données
                  +--> bloc de données
Avec triple indirection, on ajoute encore un niveau.

6.2. Idée à retenir

Le système est conçu pour être efficace pour les petits fichiers tout en permettant de gérer de gros fichiers.

À retenir :

Code: Select all

petit fichier -> pointeurs directs
gros fichier  -> pointeurs indirects, double indirects, triple indirects
7. Le VFS : Virtual File System

Le VFS est une couche d’abstraction du noyau Linux.

Son rôle est de fournir une interface commune à tous les systèmes de fichiers.

Un programme utilisateur appelle :

Code: Select all

open()
read()
write()
close()
stat()
mkdir()
rmdir()
unlink()
rename()
Le programme ne sait pas forcément si le fichier est sur :

Code: Select all

ext4
xfs
btrfs
tmpfs
procfs
sysfs
nfs
vfat
ntfs
C’est le VFS qui redirige l’opération vers le bon système de fichiers.

7.1. Schéma du VFS

Code: Select all

Application utilisateur
        |
        v
Appels système :
open(), read(), write(), stat(), unlink()
        |
        v
VFS
        |
        +--> driver ext4
        +--> driver xfs
        +--> driver btrfs
        +--> driver tmpfs
        +--> driver procfs
        +--> driver nfs
7.2. Pourquoi le VFS est important ?

Sans VFS, chaque programme devrait connaître les détails de chaque système de fichiers.

Avec VFS, le programme utilise une interface unique.

Exemple :

Code: Select all

int fd = open("fichier.txt", O_RDONLY);
read(fd, buffer, sizeof(buffer));
close(fd);
Ce code peut fonctionner sur ext4, tmpfs, nfs ou procfs, même si le fonctionnement interne est très différent.

7.3. Comparaison avec Windows

Sous Windows, une application appelle par exemple :

Code: Select all

CreateFile()
ReadFile()
WriteFile()
CloseHandle()
Derrière, le noyau et les drivers de systèmes de fichiers gèrent NTFS, FAT, exFAT, réseau, etc.

Sous Linux, l’idée équivalente est :

Code: Select all

open()
read()
write()
close()
        |
        v
VFS
        |
        v
système de fichiers réel
8. Systèmes de fichiers journalisés

Un système de fichiers doit rester cohérent.

Problème : que se passe-t-il si le système plante pendant une écriture ?

Exemple :
  • l’inode a été modifié ;
  • mais l’entrée de répertoire n’a pas encore été écrite ;
  • ou les blocs ont été alloués ;
  • mais les métadonnées ne sont pas encore cohérentes.
Après un crash, le système de fichiers peut se retrouver dans un état incohérent.

8.1. Rôle du journal

Un système de fichiers journalisé écrit d’abord dans un journal les opérations qu’il va effectuer.

Principe simplifié :

Code: Select all

1. écrire dans le journal ce qui va être modifié
2. appliquer réellement les modifications
3. marquer l’opération comme terminée
Après un crash, le système peut relire le journal pour savoir quelles opérations étaient en cours.

Cela permet une récupération beaucoup plus rapide qu’une vérification complète du disque.

8.2. Exemples

Systèmes non journalisés ou historiquement non journalisés :

Code: Select all

ext2
Systèmes journalisés :

Code: Select all

ext3
ext4
xfs
btrfs
jfs
reiserfs
Ext3 peut être vu historiquement comme une évolution d’ext2 avec journalisation.

Ext4 est plus moderne et apporte d’autres améliorations.

9. Arborescence unique et points de montage

Linux utilise une seule arborescence globale.

Elle commence à :

Code: Select all

/
Contrairement à Windows, Linux ne présente pas les partitions principalement comme :

Code: Select all

C:\
D:\
E:\
Linux attache les systèmes de fichiers à des répertoires appelés points de montage.

Exemple :

Code: Select all

/dev/sda1 -> /
/dev/sda2 -> /home
/dev/sdb1 -> /mnt/usb
tmpfs     -> /run
procfs    -> /proc
sysfs     -> /sys
9.1. Point de montage

Un point de montage est un répertoire sur lequel un système de fichiers est attaché.

Exemple :

Code: Select all

mount /dev/sdb1 /mnt/usb
Après cette commande, le contenu de la partition `/dev/sdb1` devient visible dans :

Code: Select all

/mnt/usb
Le répertoire `/mnt/usb` devient la porte d’entrée vers ce système de fichiers.

9.2. Contenu masqué par un montage

Si le répertoire utilisé comme point de montage contenait déjà des fichiers, ceux-ci ne sont pas supprimés.

Ils sont simplement masqués tant que le montage est actif.

Exemple :

Code: Select all

/mnt/test contient :
    ancien.txt

mount /dev/sdb1 /mnt/test
Pendant le montage, le contenu visible dans `/mnt/test` est celui de `/dev/sdb1`.

`ancien.txt` existe toujours, mais il est caché par le montage.

Après démontage :

Code: Select all

umount /mnt/test
Le contenu original redevient visible.

10. Monter et démonter un système de fichiers

La commande utilisateur classique pour monter est :

Code: Select all

mount
L’appel système correspondant est :

Code: Select all

mount()
Pour démonter :

Code: Select all

umount
Les appels système correspondants sont :

Code: Select all

umount()
umount2()
10.1. API mount()

Prototype :

Code: Select all

#include <sys/mount.h>

int mount(const char *source,
          const char *target,
          const char *filesystemtype,
          unsigned long mountflags,
          const void *data);
Paramètres :
  • source : périphérique ou source à monter ;
  • target : point de montage ;
  • filesystemtype : type de système de fichiers ;
  • mountflags : options de montage ;
  • data : options spécifiques au système de fichiers.
Exemple conceptuel :

Code: Select all

mount("/dev/sdb1", "/mnt/usb", "ext4", 0, NULL);
Retour :

Code: Select all

0  -> succès
-1 -> erreur, errno contient la raison
10.2. API umount()

Prototype :

Code: Select all

#include <sys/mount.h>

int umount(const char *target);
Exemple :

Code: Select all

umount("/mnt/usb");
Cela détache le système de fichiers monté sur `/mnt/usb`.

Retour :

Code: Select all

0  -> succès
-1 -> erreur
10.3. API umount2()

Prototype :

Code: Select all

#include <sys/mount.h>

int umount2(const char *target, int flags);
`umount2()` est une version plus flexible de `umount()`.

Elle permet de préciser des flags.

Flags importants :

Code: Select all

MNT_FORCE
MNT_DETACH
MNT_EXPIRE
10.4. MNT_DETACH : lazy unmount

`MNT_DETACH` réalise un lazy unmount.

Cela signifie que le montage est détaché immédiatement de l’arborescence, mais les ressources ne sont réellement libérées que plus tard, quand plus aucun processus ne les utilise.

Schéma :

Code: Select all

umount normal :
    échoue si le montage est occupé

umount2 + MNT_DETACH :
    retire le montage de l’arborescence
    libère réellement plus tard
Important :

Code: Select all

MNT_DETACH ne tue pas les processus.
Il ne force pas brutalement la fermeture des fichiers. Il détache simplement le montage de la vue globale.

10.5. MNT_FORCE

`MNT_FORCE` demande un démontage forcé.

Il est surtout utile pour certains systèmes de fichiers réseau, par exemple dans des cas où un serveur distant ne répond plus.

Attention :

Code: Select all

MNT_FORCE n’est pas un bouton magique.
Sur des systèmes locaux, il ne permet pas toujours de démonter proprement si des fichiers sont encore utilisés.

10.6. MNT_EXPIRE

`MNT_EXPIRE` sert à marquer un montage comme expiré.

C’est principalement utile avec certains mécanismes d’automount.

Principe simplifié :
  • un premier appel peut marquer le montage comme expiré ;
  • un second appel peut le démonter s’il n’est toujours pas utilisé.
11. Pourquoi un démontage peut échouer ?

Un démontage peut échouer si le système de fichiers est occupé.

Exemples :
  • un processus a un fichier ouvert dans ce système de fichiers ;
  • un terminal a son répertoire courant dans ce système de fichiers ;
  • un exécutable lancé se trouve sur ce système de fichiers ;
  • une bibliothèque utilisée vient de ce montage ;
  • un sous-montage existe encore.
Exemple classique :

Code: Select all

cd /mnt/usb
umount /mnt/usb
Le démontage peut échouer, car le shell utilise `/mnt/usb` comme répertoire courant.

12. Fonctions avancées de montage

Linux permet des montages plus avancés que le simple montage d’une partition sur un répertoire.

Le chapitre présente notamment :
  • le montage d’un même système de fichiers à plusieurs endroits ;
  • l’empilement de montages sur un même point ;
  • les flags par point de montage ;
  • les bind mounts ;
  • les recursive bind mounts.
12.1. Monter le même système de fichiers à plusieurs endroits

Linux permet de monter le même système de fichiers sur plusieurs points de montage.

Exemple :

Code: Select all

mount /dev/sda12 /testfs
mount /dev/sda12 /demo
Le même système de fichiers devient visible à deux endroits :

Code: Select all

/testfs
/demo
Ce n’est pas une copie.

Si tu crées un fichier via `/testfs`, tu le verras aussi via `/demo`.

Schéma :

Code: Select all

/dev/sda12
    |
    +--> /testfs
    |
    +--> /demo
12.2. Empiler plusieurs montages sur le même point

Linux permet de monter plusieurs systèmes de fichiers au même endroit.

Exemple :

Code: Select all

mount /dev/sda12 /testfs
mount /dev/sda13 /testfs
Le deuxième montage masque le premier.

Schéma :

Code: Select all

/testfs -> /dev/sda13 visible
          /dev/sda12 caché dessous
Quand on démonte le montage supérieur, le montage inférieur redevient visible.

C’est une logique de pile :

Code: Select all

haut de pile : montage visible
dessous      : montages masqués
À retenir :

Code: Select all

Un montage peut masquer le contenu précédent,
mais il ne le supprime pas.
12.3. Flags de montage par point de montage

Certains flags peuvent être liés à un point de montage particulier.

Cela signifie que le même système de fichiers peut être visible à deux endroits avec des options différentes.

Exemple conceptuel :

Code: Select all

mount /dev/sda12 /testfs
mount /dev/sda12 /demo
mount -o remount,noexec /demo
On peut imaginer :

Code: Select all

/testfs -> exécution autorisée
/demo   -> exécution interdite avec noexec
Le contenu est le même, mais certaines règles d’accès peuvent différer selon le point de montage.

13. Options et flags de montage importants

Voici les flags importants à connaître.

13.1. MS_RDONLY

Monte le système de fichiers en lecture seule.

Code: Select all

MS_RDONLY
Effet :

Code: Select all

Aucune écriture n’est possible.
Ce n’est pas seulement “les utilisateurs normaux ne peuvent pas écrire”. Le montage lui-même est en lecture seule.

13.2. MS_NOEXEC

Interdit l’exécution de programmes depuis ce système de fichiers.

Code: Select all

MS_NOEXEC
Effet :

Code: Select all

Les fichiers ne peuvent pas être exécutés depuis ce montage.
Cela peut être utilisé pour limiter les risques sur des partitions de données ou des répertoires temporaires.

13.3. MS_NOSUID

Ignore les bits set-user-ID et set-group-ID.

Code: Select all

MS_NOSUID
Effet :

Code: Select all

Les programmes setuid/setgid ne donnent pas d’élévation via ce montage.
C’est une option de sécurité importante.

13.4. MS_NODEV

Interdit l’interprétation des fichiers spéciaux de périphériques.

Code: Select all

MS_NODEV
Effet :

Code: Select all

Les fichiers périphériques présents sur ce système de fichiers ne sont pas utilisables comme périphériques.
C’est utile pour éviter qu’un montage non fiable expose des périphériques dangereux.

13.5. MS_NOATIME

Empêche la mise à jour du temps de dernier accès.

Code: Select all

MS_NOATIME
Normalement, quand un fichier est lu, son timestamp `atime` peut être modifié.

Avec `MS_NOATIME`, cette mise à jour est évitée.

Intérêt :
  • moins d’écritures disque ;
  • meilleures performances dans certains cas ;
  • moins d’usure sur certains supports.
13.6. MS_NODIRATIME

Semblable à `MS_NOATIME`, mais ciblé sur les répertoires.

Code: Select all

MS_NODIRATIME
Effet :

Code: Select all

Ne met pas à jour l’atime des répertoires.
13.7. MS_RELATIME

`MS_RELATIME` est une optimisation intermédiaire.

Au lieu de mettre à jour `atime` à chaque lecture, le noyau le met à jour seulement dans certains cas.

C’est souvent un compromis entre :
  • la précision des timestamps ;
  • les performances ;
  • la réduction des écritures.
13.8. MS_REMOUNT

Permet de remonter un système de fichiers déjà monté avec de nouvelles options.

Code: Select all

MS_REMOUNT
Important :

Code: Select all

MS_REMOUNT ne démonte pas puis remonte complètement.
Il modifie les options du montage à la volée.

Exemple conceptuel :

Code: Select all

mount(NULL, "/mnt/test", NULL, MS_REMOUNT | MS_RDONLY, NULL);
Ou en ligne de commande :

Code: Select all

mount -o remount,ro /mnt/test
13.9. MS_BIND

Permet de créer un bind mount.

Code: Select all

MS_BIND
Un bind mount rend un fichier ou un répertoire existant visible ailleurs dans l’arborescence.

13.10. MS_REC

Utilisé avec `MS_BIND` pour faire un bind mount récursif.

Code: Select all

MS_BIND | MS_REC
Cela permet de reprendre aussi les sous-montages présents sous le répertoire source.

14. Bind mounts

Un bind mount permet de rendre une partie déjà existante de l’arborescence visible à un autre endroit.

Commande :

Code: Select all

mount --bind source target
Appel système :

Code: Select all

mount(source, target, NULL, MS_BIND, NULL);
Exemple :

Code: Select all

mkdir /mnt/projet
mount --bind /home/jean/projet /mnt/projet
Après cela :

Code: Select all

/home/jean/projet
/mnt/projet
montrent le même contenu.

14.1. Bind mount : ce que ce n’est pas

Un bind mount n’est pas :
  • une copie ;
  • un lien symbolique ;
  • un nouveau système de fichiers ;
  • une duplication des blocs ;
  • une duplication d’inodes.
Il s’agit d’une autre visibilité vers le même objet ou la même partie de l’arborescence.

À retenir :

Code: Select all

bind mount = même contenu visible ailleurs
14.2. Différence avec un lien symbolique

Un lien symbolique est un fichier spécial contenant un chemin texte.

Exemple :

Code: Select all

ln -s /home/jean/projet /mnt/projet
Le lien symbolique pointe vers un chemin.

Un bind mount, lui, est géré au niveau du noyau dans la table des montages.

Différence :

Code: Select all

symlink :
    chemin texte vers une cible

bind mount :
    montage réel d’une partie de l’arborescence ailleurs
14.3. Différence avec un hard link

Un hard link associe un autre nom au même inode.

Mais les hard links sur répertoire sont généralement interdits pour éviter des incohérences dans l’arborescence.

Le bind mount, lui, peut exposer un répertoire entier ailleurs.

Différence :

Code: Select all

hard link :
    autre nom pour le même inode, surtout pour fichiers

bind mount :
    expose un fichier ou un répertoire ailleurs dans l’arborescence
14.4. Bind mount sur un fichier

Un bind mount peut aussi concerner un fichier.

Exemple conceptuel :

Code: Select all

touch f1
touch f2
mount --bind f1 f2
Après cela, accéder à `f2` revient à accéder à `f1`.

Le fichier cible devient lui-même un point de montage.

14.5. Utilisations des bind mounts

Les bind mounts sont très utilisés pour :
  • les environnements chroot ;
  • les containers ;
  • l’isolation de systèmes ;
  • la réorganisation temporaire de l’arborescence ;
  • l’exposition contrôlée de certains répertoires ;
  • le montage de `/dev`, `/proc`, `/sys` dans une racine isolée.
Exemple typique :

Code: Select all

mount --bind /dev  /newroot/dev
mount --bind /proc /newroot/proc
mount --bind /sys  /newroot/sys
15. Recursive bind mounts

Un bind mount simple ne reprend pas forcément tous les sous-montages présents sous le répertoire source.

Le recursive bind mount permet de reprendre aussi les sous-montages.

Commande :

Code: Select all

mount --rbind source target
Appel système :

Code: Select all

mount(source, target, NULL, MS_BIND | MS_REC, NULL);
15.1. Différence entre bind et rbind

Exemple :

Code: Select all

/source
    fichier.txt
    submount/     -> autre système de fichiers monté ici
Avec :

Code: Select all

mount --bind /source /target
Le répertoire `/source` devient visible dans `/target`, mais les sous-montages ne sont pas forcément repris comme tels.

Avec :

Code: Select all

mount --rbind /source /target
Les sous-montages sont également répliqués.

À retenir :

Code: Select all

--bind  -> répertoire ou fichier source
--rbind -> source + sous-montages
16. tmpfs

`tmpfs` est un système de fichiers en mémoire virtuelle.

Il permet de créer un système de fichiers dont les fichiers résident en mémoire, avec possibilité d’utiliser le swap si nécessaire.

Commande :

Code: Select all

mount -t tmpfs tmpfs /mnt/ram
Exemple :

Code: Select all

mkdir /mnt/ram
mount -t tmpfs tmpfs /mnt/ram
Les fichiers créés dans `/mnt/ram` sont stockés dans tmpfs.

16.1. tmpfs et persistance

Un tmpfs n’est pas persistant.

Les données disparaissent :
  • au démontage ;
  • au redémarrage ;
  • si le système de fichiers temporaire est supprimé.
Comparaison :

Code: Select all

ext4 sur disque :
    données persistantes

tmpfs :
    données temporaires en mémoire virtuelle
16.2. tmpfs et swap

Même si tmpfs est souvent décrit comme “en RAM”, il utilise en réalité la mémoire virtuelle.

Cela signifie que certaines pages peuvent être déplacées vers le swap si nécessaire.

Donc, phrase précise :

Code: Select all

tmpfs stocke ses données en mémoire virtuelle,
avec possibilité d’utiliser le swap.
16.3. Utilisations de tmpfs

`tmpfs` est utilisé pour :
  • des fichiers temporaires ;
  • des données runtime ;
  • certains mécanismes IPC ;
  • la mémoire partagée POSIX ;
  • des répertoires comme `/run` ou `/dev/shm` selon les systèmes.
Exemples :

Code: Select all

/run
/dev/shm
/tmp
selon la distribution et la configuration.

17. stat(), lstat(), fstat()

Ces fonctions servent à obtenir des informations sur un fichier.

Elles remplissent une structure :

Code: Select all

struct stat
17.1. stat()

Prototype :

Code: Select all

#include <sys/stat.h>

int stat(const char *pathname, struct stat *statbuf);
`stat()` prend un chemin et remplit une structure `stat`.

Exemple :

Code: Select all

struct stat st;

if (stat("test.txt", &st) == -1) {
    perror("stat");
}
17.2. lstat()

Prototype :

Code: Select all

int lstat(const char *pathname, struct stat *statbuf);
`lstat()` ressemble à `stat()`, mais avec une différence importante pour les liens symboliques.

Différence :

Code: Select all

stat("lien")  -> suit le lien symbolique
lstat("lien") -> donne les infos du lien lui-même
17.3. fstat()

Prototype :

Code: Select all

int fstat(int fd, struct stat *statbuf);
`fstat()` prend un descripteur de fichier déjà ouvert.

Exemple :

Code: Select all

int fd = open("test.txt", O_RDONLY);

struct stat st;

if (fstat(fd, &st) == -1) {
    perror("fstat");
}
À retenir :

Code: Select all

stat()  -> chemin
lstat() -> chemin, mais ne suit pas le symlink
fstat() -> fd
17.4. Structure stat

Exemple simplifié :

Code: Select all

struct stat {
    dev_t     st_dev;
    ino_t     st_ino;
    mode_t    st_mode;
    nlink_t   st_nlink;
    uid_t     st_uid;
    gid_t     st_gid;
    off_t     st_size;
    blksize_t st_blksize;
    blkcnt_t  st_blocks;
    time_t    st_atime;
    time_t    st_mtime;
    time_t    st_ctime;
};
Champs importants :
  • st_dev : périphérique contenant le fichier ;
  • st_ino : numéro d’inode ;
  • st_mode : type de fichier + permissions ;
  • st_nlink : nombre de liens physiques ;
  • st_uid : UID du propriétaire ;
  • st_gid : GID du groupe ;
  • st_size : taille du fichier ;
  • st_blksize : taille de bloc préférée pour les E/S ;
  • st_blocks : nombre de blocs alloués ;
  • st_atime : dernier accès ;
  • st_mtime : dernière modification du contenu ;
  • st_ctime : dernier changement de métadonnées.
Attention :

Code: Select all

ctime ne veut pas dire creation time.
ctime = change time.
17.5. Tester le type d’un fichier

Le champ utilisé est :

Code: Select all

st_mode
Macros utiles :

Code: Select all

S_ISREG(st.st_mode)   // fichier régulier
S_ISDIR(st.st_mode)   // répertoire
S_ISLNK(st.st_mode)   // lien symbolique
S_ISCHR(st.st_mode)   // périphérique caractère
S_ISBLK(st.st_mode)   // périphérique bloc
S_ISFIFO(st.st_mode)  // FIFO
S_ISSOCK(st.st_mode)  // socket
Exemple :

Code: Select all

if (S_ISREG(st.st_mode)) {
    printf("fichier regulier\n");
}

if (S_ISDIR(st.st_mode)) {
    printf("repertoire\n");
}
18. statvfs() et fstatvfs()

`stat()`, `lstat()` et `fstat()` donnent des informations sur un fichier.

Mais parfois, on veut des informations sur le système de fichiers lui-même.

Exemples :
  • taille des blocs ;
  • nombre total de blocs ;
  • nombre de blocs libres ;
  • nombre d’inodes ;
  • longueur maximale d’un nom de fichier ;
  • flags du système de fichiers.
Pour cela, on utilise :

Code: Select all

statvfs()
fstatvfs()
18.1. API statvfs()

Prototype :

Code: Select all

#include <sys/statvfs.h>

int statvfs(const char *pathname, struct statvfs *buf);
Exemple :

Code: Select all

struct statvfs sv;

if (statvfs("/", &sv) == -1) {
    perror("statvfs");
}
`statvfs()` prend un chemin et donne des informations sur le système de fichiers contenant ce chemin.

18.2. API fstatvfs()

Prototype :

Code: Select all

#include <sys/statvfs.h>

int fstatvfs(int fd, struct statvfs *buf);
`fstatvfs()` prend un descripteur de fichier.

Comparaison :

Code: Select all

statvfs()  -> chemin
fstatvfs() -> fd
Comme :

Code: Select all

stat()  -> chemin
fstat() -> fd
18.3. Structure statvfs

Exemple simplifié :

Code: Select all

struct statvfs {
    unsigned long  f_bsize;
    unsigned long  f_frsize;
    fsblkcnt_t     f_blocks;
    fsblkcnt_t     f_bfree;
    fsblkcnt_t     f_bavail;
    fsfilcnt_t     f_files;
    fsfilcnt_t     f_ffree;
    fsfilcnt_t     f_favail;
    unsigned long  f_fsid;
    unsigned long  f_flag;
    unsigned long  f_namemax;
};
Champs importants :
  • f_bsize : taille de bloc préférée pour les E/S ;
  • f_frsize : taille fondamentale des fragments ;
  • f_blocks : nombre total de blocs ;
  • f_bfree : nombre total de blocs libres ;
  • f_bavail : blocs disponibles pour utilisateur non privilégié ;
  • f_files : nombre total d’inodes ;
  • f_ffree : nombre d’inodes libres ;
  • f_favail : inodes disponibles pour utilisateur non privilégié ;
  • f_fsid : identifiant du système de fichiers ;
  • f_flag : flags ;
  • f_namemax : longueur maximale d’un nom de fichier.
18.4. Différence entre f_bfree et f_bavail

Point important :

Code: Select all

f_bfree  = blocs libres réels
f_bavail = blocs libres disponibles pour utilisateur non privilégié
Pourquoi une différence ?

Parce qu’un système peut réserver une partie de l’espace pour root ou pour le système.

Donc un utilisateur normal peut voir moins d’espace disponible que le total réellement libre.

18.5. Exemple de code statvfs()

Code: Select all

#include <stdio.h>
#include <sys/statvfs.h>

int main(void)
{
    struct statvfs sv;

    if (statvfs("/", &sv) == -1) {
        perror("statvfs");
        return 1;
    }

    printf("Block size              : %lu\n", sv.f_bsize);
    printf("Fragment size           : %lu\n", sv.f_frsize);
    printf("Total blocks            : %lu\n", sv.f_blocks);
    printf("Free blocks             : %lu\n", sv.f_bfree);
    printf("Available blocks        : %lu\n", sv.f_bavail);
    printf("Total inodes            : %lu\n", sv.f_files);
    printf("Free inodes             : %lu\n", sv.f_ffree);
    printf("Max filename length     : %lu\n", sv.f_namemax);

    return 0;
}
19. Lire la liste des systèmes montés

Pour obtenir la liste des systèmes de fichiers montés, on peut lire :

Code: Select all

/proc/mounts
/etc/mtab
/etc/fstab
19.1. /proc/mounts

`/proc/mounts` expose les montages actuellement actifs.

Commande :

Code: Select all

cat /proc/mounts
C’est généré par le noyau via procfs.

19.2. /etc/fstab

`/etc/fstab` contient la configuration des montages automatiques.

Exemple d’entrée :

Code: Select all

/dev/sda1  /  ext4  defaults  0  1
Champs typiques :
  • source ou périphérique ;
  • point de montage ;
  • type du système de fichiers ;
  • options ;
  • option dump ;
  • ordre fsck.
19.3. /etc/mtab

Historiquement, `/etc/mtab` listait les systèmes de fichiers actuellement montés.

Sur beaucoup de systèmes modernes, il peut être un lien vers `/proc/mounts`.

19.4. API getmntent()

Pour lire les entrées de montage en C, on peut utiliser :

Code: Select all

#include <mntent.h>

FILE *setmntent(const char *filename, const char *type);
struct mntent *getmntent(FILE *stream);
int endmntent(FILE *stream);
Exemple :

Code: Select all

#include <stdio.h>
#include <mntent.h>

int main(void)
{
    FILE *fp;
    struct mntent *ent;

    fp = setmntent("/proc/mounts", "r");
    if (fp == NULL) {
        perror("setmntent");
        return 1;
    }

    while ((ent = getmntent(fp)) != NULL) {
        printf("source : %s\n", ent->mnt_fsname);
        printf("target : %s\n", ent->mnt_dir);
        printf("type   : %s\n", ent->mnt_type);
        printf("opts   : %s\n\n", ent->mnt_opts);
    }

    endmntent(fp);
    return 0;
}
19.5. Structure mntent

La structure contient typiquement :

Code: Select all

struct mntent {
    char *mnt_fsname;
    char *mnt_dir;
    char *mnt_type;
    char *mnt_opts;
    int   mnt_freq;
    int   mnt_passno;
};
Champs :
  • mnt_fsname : source du montage ;
  • mnt_dir : point de montage ;
  • mnt_type : type de système de fichiers ;
  • mnt_opts : options ;
  • mnt_freq : champ lié à dump ;
  • mnt_passno : ordre de vérification fsck.
20. Différence entre struct stat, dirent, statvfs et mntent

Il faut bien distinguer ces structures.

20.1. struct stat

Sert à obtenir les informations sur un fichier.

Utilisée avec :

Code: Select all

stat()
lstat()
fstat()
Elle donne :
  • type de fichier ;
  • permissions ;
  • inode ;
  • taille ;
  • propriétaire ;
  • groupe ;
  • timestamps ;
  • nombre de liens.
Résumé :

Code: Select all

struct stat = infos sur un fichier
20.2. struct dirent

Sert à parcourir les entrées d’un répertoire.

Utilisée avec :

Code: Select all

opendir()
readdir()
closedir()
Elle donne notamment le nom de l’entrée :

Code: Select all

entry->d_name
Résumé :

Code: Select all

struct dirent = entrée de répertoire
20.3. struct statvfs

Sert à obtenir des informations sur un système de fichiers.

Utilisée avec :

Code: Select all

statvfs()
fstatvfs()
Elle donne :
  • taille des blocs ;
  • nombre de blocs ;
  • blocs libres ;
  • inodes libres ;
  • flags ;
  • taille maximale des noms.
Résumé :

Code: Select all

struct statvfs = infos globales sur le système de fichiers
20.4. struct mntent

Sert à lire les entrées de montage depuis `/proc/mounts`, `/etc/mtab` ou `/etc/fstab`.

Utilisée avec :

Code: Select all

setmntent()
getmntent()
endmntent()
Elle donne :
  • source ;
  • point de montage ;
  • type ;
  • options.
Résumé :

Code: Select all

struct mntent = infos sur les montages
20.5. Tableau mental

Code: Select all

struct stat
    -> infos sur un fichier

struct dirent
    -> entrée dans un répertoire

struct statvfs
    -> infos sur le système de fichiers

struct mntent
    -> infos sur les montages
21. Commandes importantes

21.1. Voir les périphériques bloc

Code: Select all

lsblk
Exemple :

Code: Select all

lsblk
lsblk -f
Permet de voir les disques, partitions, systèmes de fichiers et points de montage.

21.2. Voir les UUID

Code: Select all

blkid
Affiche les UUID et types de systèmes de fichiers.

21.3. Voir les montages

Code: Select all

mount
findmnt
cat /proc/mounts
21.4. Voir l’espace disque

Code: Select all

df -h
21.5. Monter un système de fichiers

Code: Select all

mount /dev/sdb1 /mnt/test
mount -t ext4 /dev/sdb1 /mnt/test
21.6. Monter en lecture seule

Code: Select all

mount -o ro /dev/sdb1 /mnt/test
21.7. Remonter avec de nouvelles options

Code: Select all

mount -o remount,ro /mnt/test
mount -o remount,noexec /mnt/test
21.8. Bind mount

Code: Select all

mount --bind /source /target
21.9. Recursive bind mount

Code: Select all

mount --rbind /source /target
21.10. Monter un tmpfs

Code: Select all

mount -t tmpfs tmpfs /mnt/ram
21.11. Démonter

Code: Select all

umount /mnt/test
21.12. Lazy unmount

Code: Select all

umount -l /mnt/test
Cela correspond à l’idée de `MNT_DETACH`.

21.13. Vérifier un système de fichiers

Code: Select all

fsck /dev/sdb1
Attention : il ne faut pas lancer `fsck` n’importe comment sur un système de fichiers monté en écriture.

22. Exemple complet : afficher le type d’un fichier

Code: Select all

#include <stdio.h>
#include <sys/stat.h>

int main(int argc, char *argv[])
{
    struct stat st;

    if (argc != 2) {
        printf("usage: %s <path>\n", argv[0]);
        return 1;
    }

    if (lstat(argv[1], &st) == -1) {
        perror("lstat");
        return 1;
    }

    if (S_ISREG(st.st_mode)) {
        printf("fichier regulier\n");
    }
    else if (S_ISDIR(st.st_mode)) {
        printf("repertoire\n");
    }
    else if (S_ISLNK(st.st_mode)) {
        printf("lien symbolique\n");
    }
    else if (S_ISCHR(st.st_mode)) {
        printf("peripherique caractere\n");
    }
    else if (S_ISBLK(st.st_mode)) {
        printf("peripherique bloc\n");
    }
    else if (S_ISFIFO(st.st_mode)) {
        printf("fifo\n");
    }
    else if (S_ISSOCK(st.st_mode)) {
        printf("socket\n");
    }
    else {
        printf("type inconnu\n");
    }

    printf("inode : %lu\n", (unsigned long)st.st_ino);
    printf("taille: %ld\n", (long)st.st_size);

    return 0;
}
23. Exemple complet : parcourir un répertoire et afficher les inodes

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>

int main(int argc, char *argv[])
{
    DIR *dir;
    struct dirent *entry;

    if (argc != 2) {
        printf("usage: %s <directory>\n", argv[0]);
        return 1;
    }

    dir = opendir(argv[1]);
    if (dir == NULL) {
        perror("opendir");
        return 1;
    }

    while ((entry = readdir(dir)) != NULL) {
        printf("nom   : %s\n", entry->d_name);
        printf("inode : %lu\n\n", (unsigned long)entry->d_ino);
    }

    closedir(dir);
    return 0;
}
24. Exemple complet : informations sur un système de fichiers

Code: Select all

#include <stdio.h>
#include <sys/statvfs.h>

int main(int argc, char *argv[])
{
    struct statvfs sv;

    if (argc != 2) {
        printf("usage: %s <path>\n", argv[0]);
        return 1;
    }

    if (statvfs(argv[1], &sv) == -1) {
        perror("statvfs");
        return 1;
    }

    printf("Taille bloc E/S       : %lu\n", sv.f_bsize);
    printf("Taille fragment       : %lu\n", sv.f_frsize);
    printf("Blocs total           : %lu\n", (unsigned long)sv.f_blocks);
    printf("Blocs libres          : %lu\n", (unsigned long)sv.f_bfree);
    printf("Blocs dispo user      : %lu\n", (unsigned long)sv.f_bavail);
    printf("Inodes total          : %lu\n", (unsigned long)sv.f_files);
    printf("Inodes libres         : %lu\n", (unsigned long)sv.f_ffree);
    printf("Nom fichier max       : %lu\n", sv.f_namemax);

    return 0;
}
25. Exemple complet : lire les montages actifs

Code: Select all

#include <stdio.h>
#include <mntent.h>

int main(void)
{
    FILE *fp;
    struct mntent *mnt;

    fp = setmntent("/proc/mounts", "r");
    if (fp == NULL) {
        perror("setmntent");
        return 1;
    }

    while ((mnt = getmntent(fp)) != NULL) {
        printf("source : %s\n", mnt->mnt_fsname);
        printf("target : %s\n", mnt->mnt_dir);
        printf("type   : %s\n", mnt->mnt_type);
        printf("opts   : %s\n\n", mnt->mnt_opts);
    }

    endmntent(fp);
    return 0;
}
26. Pièges importants du chapitre

26.1. L’inode ne contient pas le nom

Erreur fréquente :

Code: Select all

inode = nom + contenu
Correction :

Code: Select all

répertoire = nom -> inode
inode      = métadonnées + pointeurs
blocs      = contenu
26.2. statvfs() ne liste pas les montages

Erreur fréquente :

Code: Select all

statvfs() sert à récupérer la liste des montages
Correction :

Code: Select all

statvfs()  -> informations sur le système de fichiers contenant un chemin
getmntent() -> lecture des entrées de montage
26.3. MS_NOEXEC ne veut pas dire “root peut exécuter”

Erreur fréquente :

Code: Select all

noexec bloque seulement les utilisateurs normaux
Correction :

Code: Select all

MS_NOEXEC interdit l’exécution depuis ce montage.
26.4. MS_RDONLY ne veut pas dire “seul root peut écrire”

Erreur fréquente :

Code: Select all

lecture seule = seul root peut écrire
Correction :

Code: Select all

MS_RDONLY = montage en lecture seule.
Aucune écriture normale n’est autorisée via ce montage.
26.5. Bind mount n’est pas un lien symbolique

Erreur fréquente :

Code: Select all

bind mount = symlink créé par le noyau
Correction :

Code: Select all

bind mount = montage d’une partie existante de l’arborescence ailleurs.
26.6. MNT_DETACH ne tue pas les processus

Erreur fréquente :

Code: Select all

lazy unmount = tuer les processus qui utilisent le montage
Correction :

Code: Select all

MNT_DETACH détache le montage de l’arborescence.
Les ressources sont libérées quand elles ne sont plus utilisées.
26.7. MS_REMOUNT ne démonte pas puis remonte complètement

Erreur fréquente :

Code: Select all

remount = umount puis mount
Correction :

Code: Select all

MS_REMOUNT modifie les options d’un montage existant.
27. Résumé final à retenir

À retenir absolument :
  • Linux expose beaucoup de périphériques via `/dev`.
  • Les disques sont divisés en partitions.
  • Une partition peut contenir un système de fichiers.
  • Un système de fichiers organise fichiers, répertoires, inodes, blocs et métadonnées.
  • L’inode contient les métadonnées et les pointeurs vers les blocs, mais pas le nom.
  • Le nom est stocké dans une entrée de répertoire.
  • Un répertoire associe un nom à un numéro d’inode.
  • Le VFS uniformise l’accès aux différents systèmes de fichiers.
  • Les systèmes journalisés réduisent les problèmes après crash.
  • Linux utilise une seule arborescence commençant à `/`.
  • Les systèmes de fichiers sont attachés via des points de montage.
  • `mount()` monte un système de fichiers.
  • `umount()` démonte un système de fichiers.
  • `umount2()` permet un démontage avec options.
  • `MNT_DETACH` fait un lazy unmount.
  • `MNT_FORCE` force certains démontages, surtout utiles sur certains systèmes réseau.
  • `MS_RDONLY` monte en lecture seule.
  • `MS_NOEXEC` interdit l’exécution depuis le montage.
  • `MS_NOSUID` ignore les bits setuid/setgid.
  • `MS_NODEV` bloque l’usage des fichiers périphériques.
  • `MS_REMOUNT` modifie les options à la volée.
  • `MS_BIND` crée un bind mount.
  • `MS_REC` permet un bind récursif.
  • `tmpfs` est un système de fichiers en mémoire virtuelle.
  • `stat()` donne des infos sur un fichier par chemin.
  • `lstat()` donne des infos sans suivre les liens symboliques.
  • `fstat()` donne des infos sur un fichier via fd.
  • `statvfs()` donne des infos sur un système de fichiers via chemin.
  • `fstatvfs()` fait pareil via fd.
  • `getmntent()` lit les entrées de montage.
28. Tableau de synthèse des APIs

Code: Select all

API             Rôle
------------------------------------------------------------
mount()         Monter un système de fichiers
umount()        Démonter simplement un système de fichiers
umount2()       Démonter avec flags avancés
stat()          Infos sur un fichier depuis un chemin
lstat()         Infos sur un chemin sans suivre symlink
fstat()         Infos sur un fichier depuis un fd
statvfs()       Infos sur le système de fichiers depuis un chemin
fstatvfs()      Infos sur le système de fichiers depuis un fd
setmntent()     Ouvrir un fichier de table de montage
getmntent()     Lire une entrée de montage
endmntent()     Fermer la table de montage
opendir()       Ouvrir un répertoire
readdir()       Lire une entrée de répertoire
closedir()      Fermer un répertoire
29. Tableau de synthèse des structures

Code: Select all

Structure       Rôle
------------------------------------------------------------
struct stat     Informations sur un fichier
struct dirent   Entrée de répertoire
struct statvfs  Informations globales sur le système de fichiers
struct mntent   Entrée de montage
30. Tableau de synthèse des flags

Code: Select all

Flag            Rôle
------------------------------------------------------------
MS_RDONLY       Montage en lecture seule
MS_NOEXEC       Interdit l’exécution depuis le montage
MS_NOSUID       Ignore setuid/setgid
MS_NODEV        Interdit l’usage des fichiers périphériques
MS_NOATIME      Ne met pas à jour atime
MS_NODIRATIME   Ne met pas à jour atime des répertoires
MS_RELATIME     Mise à jour atime optimisée
MS_REMOUNT      Modifie les options d’un montage existant
MS_BIND         Bind mount
MS_REC          Bind récursif
MNT_DETACH      Lazy unmount
MNT_FORCE       Démontage forcé dans certains cas
MNT_EXPIRE      Expiration de montage
31. Comparaison Linux / Windows

Code: Select all

Linux :
    / comme racine unique
    points de montage
    /dev pour les périphériques
    inodes
    VFS
    open/read/write

Windows :
    C:\, D:\, E:\
    lettres de lecteur ou points de montage NTFS
    objets de périphériques
    MFT pour NTFS
    I/O Manager + drivers FS
    CreateFile/ReadFile/WriteFile
Équivalence mentale :

Code: Select all

Linux inode
    proche conceptuellement d’une entrée technique décrivant le fichier,
    mais ce n’est pas la même chose que la MFT NTFS.

Linux VFS
    comparable à une couche d’abstraction qui uniformise les systèmes de fichiers.

Linux mount point
    comparable à l’idée d’attacher un volume à un chemin,
    plutôt qu’utiliser seulement des lettres de lecteur.
Conclusion

Ce chapitre est fondamental parce qu’il explique ce qu’il y a derrière les appels simples comme :

Code: Select all

open()
read()
write()
close()
stat()
Jusqu’ici, on pouvait voir un fichier comme un simple chemin.

Après ce chapitre, il faut plutôt penser :

Code: Select all

chemin
  |
  v
répertoires successifs
  |
  v
entrée de répertoire
  |
  v
numéro d’inode
  |
  v
inode
  |
  v
blocs de données
Et pour le système complet :

Code: Select all

périphérique bloc
  |
  v
partition
  |
  v
système de fichiers
  |
  v
point de montage
  |
  v
arborescence Linux
  |
  v
VFS
  |
  v
appels système utilisateur
C’est cette vision qui permet ensuite de mieux comprendre les permissions, les liens, les montages, les containers, les environnements chroot, les systèmes de fichiers virtuels, et plus tard les mécanismes noyau liés au VFS.

Who is online

Users browsing this forum: No registered users and 1 guest