diff --git a/9.filesystems/01_Systemes_fichiers_intro.md b/9.filesystems/01_Systemes_fichiers_intro.md new file mode 100644 index 0000000000000000000000000000000000000000..d4b2b156ef09fb6ef02d67d461991490b8352ef6 --- /dev/null +++ b/9.filesystems/01_Systemes_fichiers_intro.md @@ -0,0 +1,215 @@ +--- +author: Florent Gluck - Florent.Gluck@hesge.ch + +title: Systèmes de fichiers - Introduction + +date: \vspace{.5cm} \footnotesize \today + +institute: \vspace{0.5cm} \tiny \textsuperscript{*}Remerciements à Mickaël Hoerdt + +pandoc-latex-fontsize: + - classes: [tiny] + size: tiny + - classes: [verysmall] + size: scriptsize + - classes: [small] + size: footnotesize + - classes: [huge, important] + size: huge +--- + +[//]: # ---------------------------------------------------------------- +## Historique + +\small + +:::::: {.columns} +::: {.column width="55%"} + +- Les systèmes de fichiers ont été conçu pour accéder, avec une interface simple, à des périphériques de stockage de masse (persistents) +- Premiers périphériques de stockage de masse étaient basé sur des disques magnétiques appelés *Hard Disk Drive* +- La plus petite unité de lecture/écriture adressable est le secteur +- Adressable par le triplet CHS :\ + { Cylinder, Head, Sector } + +::: +::: {.column width="45%"} + +{ width=70% } + +\tiny + +a. Plateaux +a. Bras mobile +a. Têtes de lecture/écriture reliées par le bras mobile +a. Cylindre = coupe transversale des plateaux +a. Pistes = groupe de secteurs contigüs +a. Secteur angulaire + +::: +:::::: + +[//]: # ---------------------------------------------------------------- +## Historique : premier disque dur + +\footnotesize + +Premier disque dur conçu en 1956 pour le super-computer IBM 305 Ramac + +- Capacité : 4.8MB + - \scriptsize 50 plateaux de 60cm (24"), contenant chacun 100 pistes/faces, contenant chacune 5 secteurs de 100 octets +- Débit : 8.8KB/sec. +- Vitesse : 1200 tours/min. +- 2 têtes lecture/écriture, 1 sec. pour passer d'un plateau à l'autre +- Prix du système complet : $33'200/mois + +\centering +{ width=50% } + +[//]: # ---------------------------------------------------------------- +## Aujourd'hui + +\small + +- Les **disques durs mécanique (HDD)** utilisent les mêmes principes (cylindres, pistes, têtes, des secteurs), mais : + - \footnotesize performances et capacités ont augmenté exponentiellement + - adressage physique CHS remplacé par adressage logique : LBA (*Logical Block Addressing*) + - taille physique d'un secteur est souvent 4KB avec émulation à 512 bytes par le firmware +- Les **disques durs à base de flash[^1] (SSD)** ne comportent pas de partie mécanique, mais présentent aussi des secteurs de 512 bytes adressés logiquement en LBA (émulation réalisée par le firmware) + - \footnotesize la plupart des périphiques de stockage à base de flash sont similaires (clés USB, cartes SD, etc.) + +[^1]: \tiny Flash de type NAND: [\textcolor{myblue}{https://www.arrow.com/en/research-and-events/articles/nand-memory-explained-understanding-pros-and-cons-of-nand}](https://www.arrow.com/en/research-and-events/articles/nand-memory-explained-understanding-pros-and-cons-of-nand) + + +[//]: # ---------------------------------------------------------------- +## Structure d'un disque + +\small + +- Un disque est divisé en unités de taille identique appelées **secteurs** +- La taille typique d'un secteur est 512 bytes, mais il existe des secteurs plus grands (2KB, 4KB, etc.) +- Un secteur est la plus petite unité physique pouvant être lue ou écrite +- La lecture ou l'écriture d'un secteur est une opération **atomique** + +\vspace{.2cm} + +\centering +{ width=80% } + +[//]: # ---------------------------------------------------------------- +## UNIX et blocs + +- Dans un OS de type UNIX, on parle de blocs plutôt que de secteurs +- **But : s'abstraire du type de périphérique** +- Tout périphérique dont on peut lire/écrire les données par unités de 512, 1024, etc. bytes est géré par le module noyau de +gestion de lecture/écriture par blocs +- Permet d'être indépendant du type de périphérique $\rightarrow$ généricité + +[//]: # ---------------------------------------------------------------- +## Secteurs, blocs et clusters + +\small + +- L'unité d'allocation de base des systèmes de fichiers n'est pas le secteur, mais une unité plus grande (ou égale) appelée **bloc**[^2] +- **Un bloc est une collection contiguë de secteurs** +- Un système de fichiers (FS) divise l'espace disque en blocs de taille égale +- Généralement, un bloc fait entre 1KB et 8KB +- La commande `stat fichier` affiche la taille d'un bloc du FS où se trouve `fichier` (champ *IO Block*) + +\vspace{.1cm} + +\centering +{ width=80% } + +\vspace{.3cm} + +[^2]: \footnotesize Microsoft appelle un bloc un *cluster* + +[//]: # ---------------------------------------------------------------- +## Interface périphérique bloc + +Si on fait abstraction de la gestion du cache, l'interface d'accès à un périphérique de type bloc est très simple : + +- Après initialisation de la taille d'un bloc, chaque bloc est adressable logiquement via son numéro par une fonction d'écriture et une fonction de lecture : + + + - `init_block_dev(dev, size)` + - `read_blocks(dev, block_nb, buf, count)` + - `write_blocks(dev, block_nb, buf, count)` + +[//]: # ---------------------------------------------------------------- +## Adressage + +- Les blocs d'un périphérique de taille $N$ blocs de $n$ bytes chacun, sont adressables de $0$ à $N-1$ (comme un tableau en C) +- La lecture/écriture se fait uniquement par bloc, donc par unité de $n$ bytes +- La lecture/écriture du bloc $0$ traite les bytes de l'offset $0$ à l'offset $n-1$ du périphérique +- La lecture/écriture du bloc $b$ traite les bytes de l'offset $n*b$ à l'offset $n*(b+1)-1$ + +\vspace{.3cm} + +\centering +{ width=70% } + +[//]: # ---------------------------------------------------------------- +## Adressage : exemple + +::: incremental + +Exemple : périphérique de 10MB ($1024*1024*10$ bytes), taille de bloc de 1024 bytes + +- Quelle est l'intervalle des offsets des bytes du bloc numéro 17 ? + - \textcolor{myorange}{$[1024*17,1024*(17+1)-1] = [17408,18431]$} +- Dans quel bloc se trouve le byte localisé à l'offset 7000 du périphérique ? + - \textcolor{myorange}{$7000/1024 = 6.8359375 = 6$} +- À quel offset du bloc est localisé le byte se trouvant à l'offset 7000 du périphérique ? + - \textcolor{myorange}{$7000\ \%\ 1024 = 856$} + +::: + +\vspace{.3cm} + +\centering +{ width=70% } + + +[//]: # ---------------------------------------------------------------- +## Abstraction (1/2) + +- Avec cet adressage logique, on peut facilement émuler un périphérique bloc à partir d'un fichier image +- On peut y accéder via les appels systèmes usuels `read` et `write` +- Ces appels système peuvent simplement être mappés sur les fonctions décrites précédemment : + + - \small `init_block_dev(dev, size)` $\longrightarrow$ `fd = open(file)` + - `read_blocks(dev, block_nb, buf, count)` $\longrightarrow$ `read(fd)` + - `write_blocks(dev, block_nb, buf, count)` $\longrightarrow$ `write(fd)` + + +[//]: # ---------------------------------------------------------------- +## Abstraction (2/2) + +- Le fichier image peut-être distant, si on implémente l'abstraction au dessus des sockets et d'un protocole qui +reste très simple : + + - \small `init_block_dev(dev, size)` $\longrightarrow$ `s = socket()` + - `read_blocks(block_nb, buf, count)` $\longrightarrow$ `read(s)` + - `write_blocks(block_nb, buf, count)` $\longrightarrow$ `write(s)` + +[//]: # ---------------------------------------------------------------- +## Conclusion + +::: incremental + +- On peut lire/écrire des blocs adressés logiquement, mais on est encore loin d'un FS +- Comment à partir de ces opérations simples, peut-on construire un FS ? +- Pour cela, il est nécessaire de comprendre l'allocation des blocs de données ainsi que l'organisation sur disque d'un FS + +::: + +[//]: # ---------------------------------------------------------------- +## Ressources + +\small + +- Operating Systems: Three Easy Pieces, Remzi H. and Andrea C. Arpaci-Dusseau. Arpaci-Dusseau Books\ +\footnotesize [\textcolor{myblue}{http://pages.cs.wisc.edu/~remzi/OSTEP/}](http://pages.cs.wisc.edu/~remzi/OSTEP/) + - livre disponible à la bibliothèque diff --git a/9.filesystems/02_Systemes_fichiers_strategies_alloc.md b/9.filesystems/02_Systemes_fichiers_strategies_alloc.md new file mode 100644 index 0000000000000000000000000000000000000000..c153404172713290b4975d6b71e6984f0cc866dd --- /dev/null +++ b/9.filesystems/02_Systemes_fichiers_strategies_alloc.md @@ -0,0 +1,375 @@ +--- +author: Florent Gluck - Florent.Gluck@hesge.ch + +title: Systèmes de fichiers - Stratégies d'allocation + +date: \vspace{.5cm} \footnotesize \today + +pandoc-latex-fontsize: + - classes: [tiny] + size: tiny + - classes: [verysmall] + size: scriptsize + - classes: [small] + size: footnotesize + - classes: [huge, important] + size: huge +--- + +## TODO + +- Update FAT diagram: + - indicate a file's metadata with: first block, file size (along the type), type, etc. +- Update inode diagram: + - indicate a file's inode with: file size (along the type), permission, type, etc. and block pointers + - specify an inode has a fixed size + - update diagram to show the data blocks to "scale", especially vs an inode +- ext4: indicate that very small files' content is stored in the inode and don't use a data block +- would be good to the number of single ptr, indirect ptr, etc. for ext2, ext3 and ext4 + +[//]: # ---------------------------------------------------------------- +## Système de fichiers + +- Un système de fichiers (FS) est un ensemble de fichiers +- Les fichiers stockent des données +- Les fichiers et les répertoires sont tous deux des fichiers, mais de types différents +- Du point de vue du FS : + - un fichier ordinaire contient... les données du fichier + - un répertoires contient des entrées de répertoire (cf. suite du cours) +- Fichiers et répertoires sont représentés de la même manière, mais leurs contenus sont différents + +[//]: # ---------------------------------------------------------------- +## Fichier + +Un fichier est composé de deux parties : + +- **Métadonnées** + - type, permissions, (nom), propriétaire, pointeurs vers les données, etc. +- **Données (contenu)** + - fichier "ordinaire" : blocs contenant le contenu du fichier + - répertoire : blocs contenant les références vers les fichiers présents dans le répertoire + +[//]: # ---------------------------------------------------------------- +## Défi + +- Comment organiser un FS hiérarchique en utilisant des blocs comme unité de base ? +- Comment rendre le FS performant ? + - en termes d'espace (pas d'espace perdu) + - en terme de lecture et d'écriture de fichiers + +[//]: # ---------------------------------------------------------------- +## Stratégies d'allocation des blocs de données + +- La création d'un fichier ou d'un répertoire nécessite **d'allouer des blocs** +- La stratégie d'allocation des blocs de données (contenu) doit : + - être efficace en termes d'espace + - garantir un accès rapide aux fichiers + +[//]: # ---------------------------------------------------------------- +## Métriques d'allocation de blocs + +Métriques principales: + +- Les fichiers peuvent-ils grandir ? +- Performance des accès séquentiels +- Performance des accès aléatoires +- Facilité d'implémentation +- Fragmentation +- Efficacité du stockage/*overhead* + +[//]: # ---------------------------------------------------------------- +## Fragmentation interne + +:::::: {.columns} +::: {.column width="50%"} + +- L'espace alloué peut être plus grand que l'espace demandé +- **L'espace alloué non utilisé est gaspillé !** + +::: +::: {.column width="50%"} + +\centering +{ width=50% } + +::: +:::::: + +[//]: # ---------------------------------------------------------------- +## Fragmentation externe + +:::::: {.columns} +::: {.column width="50%"} + +- Bien qu'il y ait suffisamment d'espace libre au total, il n'y a pas assez d'espace libre contigu pour satisfaire la demande d'allocation +- **Impossible de satisfaire la demande d'allocation !** + +::: +::: {.column width="50%"} + +\centering +{ width=80% } + +::: +:::::: + +[//]: # ---------------------------------------------------------------- +## Principales stratégies d'allocation de blocs + +- Le choix de la stratégie d'allocation dépend : + - de la technologie de stockage (SSD, HDD, etc.) + - de la stratégie d'accès et le type d'utilisation + - lecture seule, gros fichiers, petits fichiers, fichiers grandissant beaucoup, etc. + +- Stratégies d'allocation principales + 1. contiguë + 1. liste chaînée + 1. indexée + +[//]: # ---------------------------------------------------------------- +## 1 | Allocation contiguë + +- Chaque fichier utilise un ensemble de blocs contigus +- Un fichier stocke : + - l'index du premier bloc du fichier + - la taille du fichier + +[//]: # ---------------------------------------------------------------- +## 1 | Allocation contiguë : exemple + +\centering +{ width=70% } + +[//]: # ---------------------------------------------------------------- +## 1 | Allocation contiguë : synthèse + +- \textbf{\textcolor{mygreen}{Avantages}} + - très facile à implémenter + - accès séquentiel rapide + - accès aléatoire rapide + - faible *overhead* stockage (structure de données très simple) + +- \textbf{\textcolor{myred}{Inconvénients}} + - les fichiers ne peuvent pas (ou peu) grandir + - fragmentation externe importante + - fragmentation interne lorsque taille fichier < taille bloc + +[//]: # ---------------------------------------------------------------- +## 2 | Allocation par liste chaînée + +- Un fichier stocke : + - un pointeur sur le premier bloc + - la taille du fichier (ou un pointeur sur le dernier bloc) + +- Les blocs sont stockés dans une liste chaînée + - chaque bloc possède un pointeur sur le bloc suivant + + \vspace{.5cm} + { width=70% } + \vspace{.3cm} + +[//]: # ---------------------------------------------------------------- +## 2 | Allocation par liste chaînée : exemple + +\centering +{ width=70% } + +[//]: # ---------------------------------------------------------------- +## 2 | Allocation par liste chaînée : synthèse + +- \textbf{\textcolor{mygreen}{Avantages}} + - les fichiers peuvent facilement grandir, sans limite + - facile à implémenter, mais le stockage des pointeurs est délicat + - pas de fragmentation externe + +- \textbf{\textcolor{myred}{Inconvénients}} + - accès séquentiel lent + - accès aléatoire lent : adresse difficile à calculer + - fragmentation interne lorsque taille fichier < taille bloc + +[//]: # ---------------------------------------------------------------- +## 2b | Allocation par FAT + +:::::: {.columns} +::: {.column width="63%"} + +\small + +- Variante de l'allocation par liste chaînée +- Les pointeurs de blocs sont stockés dans une table dédiée située au début du FS + - taille de la table d'allocation des fichiers (FAT) + - \footnotesize une entrée FAT par bloc de données + - \footnotesize liste chaînée d'entrées FAT par fichier + - \footnotesize valeur spéciale indique la fin de la liste (EOC = *End of Chain*) +- Système fichiers de MS-DOS et Winows 95, utilisé dans cartes SD et clés USB +- Nombreuses variantes : FAT16, FAT32, exFAT, etc. + +::: +::: {.column width="37%"} + +\centering + +\vspace{.5cm} + +\small + +Structure sur disque du FS FAT + +\vspace{.5cm} + +{ width=100% } + +::: +:::::: + +[//]: # ---------------------------------------------------------------- +## 2b | Contenu de la FAT : exemple + +\centering +{ width=100% } + +[//]: # ---------------------------------------------------------------- +## 2b | FS de type FAT : exemple + +\small + +Soit le FS de type FAT suivant : + +- Le FS comporte 1'000 blocs de données +- Taille des blocs de données : 4 KB +- Chaque entrée dans la FAT est codée sur 16 bits + - une valeur est réservée pour représenter la EOC (*End Of Chain*) + +::: incremental + +**Questions** + +1. Quelle est la taille de la FAT en bytes pour ce FS\ ? + - \footnotesize \textcolor{mygreen}{$1000*(16 bits)$ = 2000 bytes} + +1. Quelle est la taille de fichier maximum supportée pour ce FS (en bytes, KB et MB)\ ? + - \footnotesize \textcolor{mygreen}{$1000*4096$ = 4096000 bytes, 4000 KB, 3.9 MB} + +1. Combien de blocs de données cette FAT pourrait-elle gérer au maximum théoriquement\ ? + - \footnotesize \textcolor{mygreen}{$(2^{16})-1$ = 65535} + +::: + +[//]: # ---------------------------------------------------------------- +## 2b | Allocation par FAT : synthèse + +- \textbf{\textcolor{mygreen}{Avantages}} + - relativement facile à implémenter + - les fichiers peuvent facilement grandir (tant qu'il y a de l'espace dans la FAT) + - accès aléatoire rapide + - pas de fragmentation externe + +- \textbf{\textcolor{myred}{Inconvénients}} + - accès séquentiel lent si les blocs ne sont pas contigus (HDD uniquement) + - *overhead* important pour le stockage de la FAT (disque et RAM), en particulier avec un grand nombre de clusters + - la FAT doit être chargée en RAM (sinon performances catastrophiques) + - fragmentation interne lorsque taille fichier < taille bloc + +[//]: # ---------------------------------------------------------------- +## 3 | Allocation indexée + +- Chaque fichier est associé à un **inode** de taille fixe +- L'inode contient + - les métadonnées du fichier + - la liste des pointeurs vers les blocs de données + +\vspace{.3cm} + +\centering +{ width=50% } + +[//]: # ---------------------------------------------------------------- +## 3b | Allocation indexée multi-niveau + +\small + +- L'inode stocke pointeurs directs, indirects, doublement indirects, etc. +- Utilisé par tous les FS dans les systèmes UNIX : minix-fs, ext2, ext3, etc. + +\centering +{ width=90% } + +[//]: # ---------------------------------------------------------------- +## 3b | Allocation indexée multi-niveau : exemple + +\small + +Soit le FS de type indexé multi-niveau suivant : + +- Un inode fait 64 bytes +- Un inode contient 8 pointeurs directs, 2 pointeurs indirects et 1 pointeur doublement indirect +- Un pointeur de bloc est stocké sur 16 bits +- Taille des blocs de données : 1 KB (1024 bytes) + +::: incremental + +**Questions** + +1. Combien peut-on stocker de pointeurs par bloc\ ? + - \footnotesize \textcolor{mygreen}{$1024/2$ = 512} + +1. Quelle est la taille de fichier maximum supportée pour ce FS (en bytes, KB et MB)\ ? + - \footnotesize \textcolor{mygreen}{$8*1024 + (512*1024)*2 + (512^2)*1024$ = 269492224 bytes, 263176 KB, 257 MB } + +::: + +<!-- +1. Combien peut-on stocker d'inodes par bloc\ ? + - \footnotesize \textcolor{mygreen}{$1024/64$ = 16} +--> + +[//]: # ---------------------------------------------------------------- +## 3b | Allocation indexée : synthèse + +- \textbf{\textcolor{mygreen}{Avantages}} + - relativement facile à implémenter + - les fichiers peuvent facilement grandir (tant qu'il y a des pointeurs libres) + - accès aléatoire rapide + - pas de fragmentation externe + +- \textbf{\textcolor{myred}{Inconvénients}} + - *overhead* de stockage pour les pointeurs + - l'accès rapide nécessite l'allocation de blocs contigus (HDD uniquement) + - sinon, accès potentiellement lent + - fragmentation interne lorsque taille fichier < taille bloc + +[//]: # ---------------------------------------------------------------- +## 3c | Allocation par extent + +- Principe similaire à l'allocation indexée +- **Différence** : un pointeur référence un **\textit{extent}** plutôt qu'un bloc +- *Extent* = ensemble de blocs contigüs + - représenté par le tuple : `{ FirstBlockAddress, Length }` +- Exemple : 64 bits par *extent* : + - 48 bits pour l'indice du 1er bloc + - 16 bits pour la longueur (= nombre de blocs) +- **Avantages** : moins de blocs à stocker si la plupart des allocations sont contiguës +- Utilisé par les FS "modernes" : ext4, btrfs, ntfs, xfs, etc. + +[//]: # ---------------------------------------------------------------- +## 3c | Allocation par extent : synthèse + +- \textbf{\textcolor{mygreen}{Avantages}} + - les fichiers peuvent grandir (tant qu'il y a des extents libres) + - accès séquentiel rapide + - accès aléatoire rapide + - faible *overhead* stockage (structure de données simple) + +- \textbf{\textcolor{myred}{Inconvénients}} + - fragmentation externe potentielle + - \ plus complexe que l'allocation indexée + - fragmentation interne lorsque taille fichier < taille bloc + +[//]: # ---------------------------------------------------------------- +## Ressources + +\small + +- Operating Systems: Three Easy Pieces, Remzi H. and Andrea C. Arpaci-Dusseau. Arpaci-Dusseau Books\ +\footnotesize [\textcolor{myblue}{http://pages.cs.wisc.edu/~remzi/OSTEP/}](http://pages.cs.wisc.edu/~remzi/OSTEP/) + - livre disponible à la bibliothèque diff --git a/9.filesystems/03_Systemes_fichiers_struct_disque.md b/9.filesystems/03_Systemes_fichiers_struct_disque.md new file mode 100644 index 0000000000000000000000000000000000000000..332a694893a3cecedae6a9320537344ed5a83fe0 --- /dev/null +++ b/9.filesystems/03_Systemes_fichiers_struct_disque.md @@ -0,0 +1,344 @@ +--- +author: Florent Gluck - Florent.Gluck@hesge.ch + +title: Systèmes de fichiers - Structure sur disque + +date: \vspace{.5cm} \footnotesize \today + +institute: \vspace{0.5cm} \tiny \textsuperscript{*}Remerciements à Mickaël Hoerdt + +pandoc-latex-fontsize: + - classes: [tiny] + size: tiny + - classes: [verysmall] + size: scriptsize + - classes: [small] + size: footnotesize + - classes: [huge, important] + size: huge +--- + +[//]: # ---------------------------------------------------------------- +## Concepts clés d'un système de fichiers stocké + +1. Quelles sont les structures de données stockées sur le disque qui organisent les méta-données et le contenu des fichiers ? + +1. Comment est-ce que ces structures de données sont-elles reliées les unes aux autres ? + +1. Quelles sont les interfaces d'accès au système de fichiers (FS) ? + - comment est-ce que le système associe p.ex. `open()`, `read()` et `write()` aux points 1 et 2 ? + +[//]: # ---------------------------------------------------------------- +## Exemple de structure simple d'un FS + +\small +Soit un FS constitué de 64 blocs + +\vspace{.2cm} + +\centering +{ width=100% } + + +[//]: # ---------------------------------------------------------------- +## Exemple de structure simple d'un FS + +\small +Le bloc 0 est réservé : contient potentiellement le secteur de boot et la table de partitions + +\vspace{.2cm} + +\centering +{ width=100% } + +[//]: # ---------------------------------------------------------------- +## Blocs de données + +\small +Pour stocker des données il est préférable que la majorité des blocs soient réservés pour cela (blocs de données) + +\vspace{.2cm} + +\centering +{ width=100% } + +[//]: # ---------------------------------------------------------------- +## Allocation des blocs de données + +\footnotesize +- Un tableau de bits indique quels blocs de données sont disponibles/utilisés +- Appelé **bitmap de blocs** +- Contient autant de bits qu'il y a de blocs de données + +\centering +{ width=100% } + +[//]: # ---------------------------------------------------------------- +## Exemple de bitmap pour les blocs de données + +\small +- Soit 3 blocs de données utilisés : 2, 3 et 6 +- Bitmap contient : 0,0,1,1,0,0,1,0,0,... + +\centering +{ width=100% } + +[//]: # ---------------------------------------------------------------- +## Allocation des blocs de données + +- Un bitmap pour allouer les blocs n'est qu'un exemple de structure d'allocation +- D'autres structures sont possibles : listes, arbres, etc. +- On peut donc allouer/libérer des blocs de données, mais on veut aussi associer des blocs à un/des fichiers + +[//]: # ---------------------------------------------------------------- +## Association blocs de données $\leftrightarrow$ fichiers + +\small +- C'est la fonction principale des **inodes** +- Les inodes contiennent également les méta-données des fichiers + +\centering +{ width=100% } + +[//]: # ---------------------------------------------------------------- +## Inodes + +- La taille d'un inode est fixe pour un FS donné +- Le inodes sont stockés de manière **contigüe** au début du FS + - appelé la **table d'inodes** +- Selon le FS, la taille varie (typiquement divise la taille d'un secteur, 512 bytes) +- La taille d'un inode est définie à la création du FS +- Un petit FS (= faible nombre de blocs) aura typiquement une taille d'inode inférieure à un grand FS +- Soit des blocs de 4 KB et une taille d'inode de 128 bytes + - combien d'inodes par bloc ? + +[//]: # ---------------------------------------------------------------- +## Table d'inodes + +\small +Exemple d'une table d'inodes utilisant 2 blocs + +- Taille de bloc : 2 KB +- Taille d'inode : 128 bytes + +**\textcolor{myred}{Les inodes sont indexés à 1}** + +\vspace{.3cm} + +\centering +{ width=75% } + +[//]: # ---------------------------------------------------------------- +## Relation fichier $\leftrightarrow$ inode + +- Chaque fichier est associé **exactement** à 1 inode +- Chaque n° d'inode est **unique** à un FS donné +- Des FS différents peuvent utiliser les mêmes n° d'inodes +- Le n° d'inode d'un fichier supprimé est réutilisé par le FS + +[//]: # ---------------------------------------------------------------- +## Historique du nom "inode" + +"In truth, I don't know either. It was just a term that we started to use. ‘Index’ is my best guess, because of the +slightly unusual file system structure that stored the access information of files as a flat array on the disk..." + +\vspace{.5cm} + +Dennis Ritchie[^1] + +[^1]: \footnotesize Un des deux principaux créateurs d'UNIX, l'autre étant Ken Thompson + +[//]: # ---------------------------------------------------------------- +## Structure d'un inode + +\small +Structure typique, mais qui peut varier en fonction du FS : + +\scriptsize + +**Champ** **Description** +-------------- ----------------------------- +`type` \textcolor{myblue}{Fichier}, \textcolor{myorange}{répertoire}, device, lien, etc. +`uid` UID du propriétaire +`gid` GID du propriétaire +`rwx` Permissions (droits d'accès) +`size` Taille en bytes +`time` Date du dernier accès +`n_links` Nombre de liens/chemins d'accès vers l'inode +`direct[N]` Pointeurs directs vers les blocs du contenu du + fichier, **dans l'ordre** +`indir[M]` Pointeurs indirects vers les blocs du contenu + du fichier, **dans l'ordre** +`dbl_indir[P]` Pointeurs doublement indirects vers les blocs + du contenu du fichier, **dans l'ordre** + +\vspace{-.3cm} +Une valeur de 0 dans les n° indique une entrée non-utilisée + +[//]: # ---------------------------------------------------------------- +## Allocation des blocs de données dans un inode + +\small +Exemple avec : 10 pointeurs directs, 1 pointeur indirect, 1 pointeur doublement indirect et 1 pointeur triplement indirect + +\vspace{.3cm} + +\centering +{ width=90% } + +[//]: # ---------------------------------------------------------------- +## Contenu des fichiers + +- Un fichier de **type \textcolor{myblue}{fichier}** est un fichier habituel dont les données (contenu) peuvent être : + - du texte si c'est un fichier texte + - des données d'image si c'est un fichier png + - des données audio si c'est un fichier flac + - etc. + +- Un fichier de **type \textcolor{myorange}{répertoire}** (*directory*) est un fichier qui contient des entrées de répertoires (*directory entries*) + +[//]: # ---------------------------------------------------------------- +## Entrée de répertoire + +- Une entrée de répertoire associe simplement un nom à un inode + +- Structure d'une entrée de répertoire (`dir_entry`) : + +**Champ** **Description** +-------------- ----------------------------- +`inode` numéro d'inode du fichier +`name` nom associé à cet inode (fichier) + +\vspace{.3cm} +**\textcolor{myred}{Un fichier n'est donc pas caractérisé par son nom, mais par son inode !}** + +[//]: # ---------------------------------------------------------------- +## Contenu d'un répertoire + +\small +- Le contenu d'un fichier de type **\textcolor{myorange}{répertoire}** contient des entrées de répertoires +- Par convention, dans la plupart des FS, l'inode n° 1 est le répertoire racine du FS : `/` + +\vspace{.2cm} + +\centering +{ width=100% } + +[//]: # ---------------------------------------------------------------- +## Liens symboliques + +\small + +- En Anglais : *soft links* ou *symbolic links* +- Un fichier de type **lien symbolique** a comme contenu (1 seul bloc de donnée) une chaîne de caractères représentant le chemin de destination du lien +- Lors de l'analyse d'un chemin d'accès, si le système rencontre un lien symbolique, alors son contenu est concaténé avec le chemin déjà parcouru +- `ln -s` permet de créer un lien symbolique +- Exemple : créé le lien symbolique `pipo.c` vers `code/src/prog.c` : + ```{.shell .verysmall} + ln -s code/src/prog.c pipo.c + ``` + +[//]: # ---------------------------------------------------------------- +## Liens symboliques : considérations importantes + +- Un lien symbolique peut pointer vers un fichier ou un répertoire +- Un lien symbolique peut traverser les FS + - il est possible de créer un lien symbolique X sur le FS1 qui pointe vers le fichier Y sur le FS2 +- Si la destination d'un lien symbolique est déplacée ou supprimée, le lien symbolique devient alors invalide\ ! + +[//]: # ---------------------------------------------------------------- +## Liens durs + +- En Anglais : *hard links* +- Un **lien dur** est simplement une nouvelle entrée de répertoire (`dir_entry`) pointant vers un inode donné +- En d'autres termes, il s'agit simplement d'un nom supplémentaire pointant vers le même inode +- `ln` permet de créer un lien dur +- Exemple : créé le lien dur `pipo.c` vers `code/src/prog.c` : + ```{.shell .verysmall} + ln code/src/prog.c pipo.c + ``` + +[//]: # ---------------------------------------------------------------- +## Liens durs : considérations importantes + +- Un lien dur ne peut pas pointer vers un répertoire +- Un lien dur ne peut pas traverser les FS car un numéro d'inode est seulement unique à un FS\ ! +- La valeur `Links` affichée par la commande `stat` indique le nombre de `dir_entry` pointant sur le fichier (inode) +- \textcolor{myred}{Un fichier (inode) n'est \textbf{réellement supprimé} que lorsque le dernier \texttt{dir\_entry} (lien dur) pointant dessus est supprimée !} + - aussi, si un descripteur de fichier ouvert référence ce fichier (inode), alors le fichier ne sera supprimé que lorsque le dernier descripteur sera fermé +- Les liens durs (ou `dir_entry`) sont donc simplement des références vers un inode (fichier) + +[//]: # ---------------------------------------------------------------- +## Allocation des inodes + +\small +- Similairement à l'allocation des blocs de données, on utilise un bitmap +- D'autres structures sont possibles : listes, arbres, etc. + +\centering +{ width=100% } + +[//]: # ---------------------------------------------------------------- +## Superblock + +\small +Le superblock stocke des informations globales sur le FS : + +- Signature du FS, nombre d'inodes total, nombre de blocs total, taille du bitmap des inodes, etc. + +\centering +{ width=100% } + +[//]: # ---------------------------------------------------------------- +## Combien d'inodes ? + +Le nombre d'inodes détermine le nombre maximum de fichiers pouvant être créés sur un FS + +\vspace{.5cm} + +**\textcolor{myred}{Combien d'inodes faut-il réserver pour un FS d'une taille donnée ?}** + +[//]: # ---------------------------------------------------------------- +## Combien d'inodes : mkfs.minix + +- `mkfs.minix` se base sur la taille du disque (`DS`) ; ci-dessous `fs_blocks` = nombre total de blocs dans le FS +- Si `DS` > 2 GB alors `inodes = fs_blocks/16` +- Si `DS` > 500 MB alors `inodes = fs_blocks/8` +- Sinon : `inodes = fs_blocks/3` +- Ensuite, arrondi au prochain multiple de la taille d'un inode (32 bytes) +- Exemple : + - soit un disque de 64 MB et des blocs de 1 KB\ + $\rightarrow$ `inodes = (64*1024/3 + 32) & 0xFFFFFFE0 = 21856` + +[//]: # ---------------------------------------------------------------- +## Combien d'inodes : mke2fs (ext2/3/4) + +- `mke2fs` se base sur un paramètre nommée \textcolor{myblue}{\texttt{bytes-per-inode}} +- Indique de créér un inode pour chaque \textcolor{myblue}{\texttt{bytes-per-inode}} bytes d'espace disque +- Exemple : + - soit un disque de 64 MB et \textcolor{myblue}{\texttt{bytes-per-inode}} = 4096\ + $\rightarrow$ `inodes = 64*1024*1024/4096 = 16384` + +[//]: # ---------------------------------------------------------------- +## Ressources + +\small + +- Operating Systems: Three Easy Pieces, Remzi H. and Andrea C. Arpaci-Dusseau. Arpaci-Dusseau Books\ +\footnotesize [\textcolor{myblue}{http://pages.cs.wisc.edu/~remzi/OSTEP/}](http://pages.cs.wisc.edu/~remzi/OSTEP/) + - livre disponible à la bibliothèque + +\small + +- `mkfs.minix` source code\ +\footnotesize [\textcolor{myblue}{https://github.com/util-linux/util-linux/blob/master/disk-utils/mkfs.minix.c}](https://github.com/util-linux/util-linux/blob/master/disk-utils/mkfs.minix.c) + +\small + +- The Second Extended File System - Internal Layout\ +\footnotesize [\textcolor{myblue}{https://www.nongnu.org/ext2-doc/ext2.html}](https://www.nongnu.org/ext2-doc/ext2.html) + +\small + +- Ext4 (and Ext2/Ext3) Wiki\ +\footnotesize [\textcolor{myblue}{https://ext4.wiki.kernel.org/index.php/Main\_Page}](https://ext4.wiki.kernel.org/index.php/Main_Page) diff --git a/9.filesystems/04_Systemes_fichiers_minix.md b/9.filesystems/04_Systemes_fichiers_minix.md new file mode 100644 index 0000000000000000000000000000000000000000..e836e80cf1e42caa5cb9820f2f712f98a061a7c9 --- /dev/null +++ b/9.filesystems/04_Systemes_fichiers_minix.md @@ -0,0 +1,572 @@ +--- +author: Florent Gluck - Florent.Gluck@hesge.ch + +title: Systèmes de fichiers - MINIX-fs + +date: \vspace{.5cm} \footnotesize \today + +institute: \vspace{0.5cm} \tiny \textsuperscript{*}Remerciements à Mickaël Hoerdt + +pandoc-latex-fontsize: + - classes: [tiny] + size: tiny + - classes: [verysmall] + size: scriptsize + - classes: [small] + size: footnotesize + - classes: [huge, important] + size: huge +--- + +## TODO + +- Ajouter slide expliquant comment débogger une image: + - en la montant puis en la parcourant +- "ls -i file" affiche le n° d'inode de "file +- "stat file" affiche n° inode, link count, etc. +- "tree --inodes -p -s -a" affiche arborescence avec n°inodes, permissions+type, tailles +- "-a" affiche également les fichiers cachés + +[//]: # ---------------------------------------------------------------- +## Introduction à MINIX-fs + +- MINIX-fs est le système de fichiers (FS) natif du système d'exploitation MINIX écrit par Andrew S. Tanenbaum en 1987 +- Le but de MINIX-fs était : + - de répliquer la structure du FS de UNIX, mais sans les fonctionnalités avancées et complexes de ce dernier + - de fournir une aide à l'enseignement des systèmes de fichiers et des OS + +[//]: # ---------------------------------------------------------------- +## Linux et MINIX-fs + +- Les premières versions du noyau Linux (1992) utilisaient MINIX-fs comme FS +- 1992 : Rémy Card implémente ext (Extended Filesystem) pour remplacer MINIX-fs + - ext est basé sur une structure similaire à MINIX-fs +- 1993 : Rémy Card publie ext2 +- 2001 : Theodore Ts'o et d'autres publient ext3 +- 2006 : la version instable de ext4 est publiée +- 2008 : la version stable de ext4 est publiée + +[//]: # ---------------------------------------------------------------- +## Versions de MINIX-fs + +- Il existe 3 versions de MINIX-fs : v1, v2 et v3 +- Nous présentons ici la v1 car c'est la plus simple +- Il existe deux variantes de MINIX-fs v1 : + - variante avec noms de fichiers de 14 caractères max (superblock magic value `0x137F`) + - variante avec noms de fichiers de 30 caractères max (superblock magic value `0x138F`) + +[//]: # ---------------------------------------------------------------- +## Comparaison MINIX-fs et ext2/3/4 + +Valeurs max pour les caractéristiques principales des FS : + +\footnotesize + +**Name** **FS** **File** **Block** **Extent** **File length** +------------- --------------- -------------------- --------------- ---------- --------------- +MINIX-fs v1.0 256 MB 256 MB 1 KB (fixed) n/a 14/30 +ext 2 GB 2 GB ? n/a 255 +ext2 32 TB 2 TB 8 KB n/a 255 +ext3 32 TB 2 TB 8 KB n/a 255 +ext4 1 EB 16 TB 4 KB 128 MB 255 + +\small + +Remarque : ext3 est simplement ext2 avec l'ajout d'un journal + +[//]: # ---------------------------------------------------------------- +## Structure générale + +\small +Structure générale sur disque de MINIX-fs v1.0 + +\vspace{.5cm} + +\centering +{ width=100% } + +[//]: # ---------------------------------------------------------------- +## Structure des inodes + +\small +Structure d'un inode dans MINIX-fs v1.0 : + +\vspace{.2cm} + +```{.c .verysmall} +struct minix_inode { + u16 i_mode; // file type and permissions for file + u16 i_uid; // user id + u32 i_size; // file size in bytes + u32 i_time; // inode time + u8 i_gid; // group id + u8 i_nlinks; // number of dir entry pointing to + // this inode + u16 i_zone[7]; // direct pointers + u16 i_indir_zone; // indirect pointer + u16 i_dbl_indir_zone; // double indirect pointer +}; +``` + +- **Important** : structure sur disque stockée selon l'ordre *little-endian* +- Taille d'un inode en bytes ? + +[//]: # ---------------------------------------------------------------- +## Structure du mode du fichier + +Format du champs `i_mode` (16 bits) de l'inode : + +\footnotesize + +**Bits** **Description** +---------------- -------------------------- --------------------------- +`12-15` Type de fichier : `0x1` : named pipe (FIFO) + `0x2` : char device + `0x4` : directory + `0x6` : block device + `0x8` : regular file + `0xA` : symbolic link +`11` SUID bit +`10` SGID bit +`9` Sticky bit +`6-8` user permissions (rwx) +`3-5` group permissions (rwx) +`0-2` others permissions (rwx) + +[//]: # ---------------------------------------------------------------- +## Structure des entrées de répertoires + +Structure d'une entrée de répertoire dans MINIX-fs v1.0 : + +\vspace{.2cm} + +```{.c .verysmall} +// Variante : superblock magic 0x137F +#define MINIX_NAME_LEN 14 + +struct minix_dir_entry { + u16 inode; + char name[MINIX_NAME_LEN]; +}; +``` + +- Taille d'un `dir_entry` en bytes ? + +[//]: # ---------------------------------------------------------------- +## Structure du superbloc + +Structure du superbloc dans MINIX-fs v1.0 : + +\vspace{.2cm} + +```{.c .tiny} +struct minix_super_block { + u16 s_ninodes; // total number of inodes + u16 s_nzones; // total number of blocks (including superblock) + u16 s_imap_blocks; // inodes bitmap size in blocks + u16 s_zmap_blocks; // data blocks bitmap size in blocks + u16 s_firstdatazone; // index of first data block + u16 s_log_zone_size; // block size in bytes = 1024*2^s_log_zone_size + u32 s_max_size; // max file size in bytes + u16 s_magic; // 0x137f = v1 with 14 characters dir_entry + // 0x138f = v1 with 30 characters dir_entry + u16 s_state; // was the FS properly unmounted? +}; +``` + +- Taille du superbloc en bytes ? + +[//]: # ---------------------------------------------------------------- +## Exemple de superbloc + +- Soit un disque de 20 MB et une taille de bloc de 1 KB\ + $\rightarrow$ `fs_blocks` = nombre de blocs au total +- Nombre inodes = `(fs_blocks/3 + 32) & 0xFFFFFFE0`[^1] + +\vspace{.2cm} + +```{.c .tiny} +struct minix_super_block { + u16 s_ninodes = 6848; // total number of inodes + u16 s_nzones = 20480; // total number of blocks + // = (20*1024^2)/1024 + u16 s_imap_blocks = 1; // inodes bitmap size in blocks + // need 6848 bits + // -> 1 block = 8192 bits + u16 s_zmap_blocks = 3; // data blocks bitmap size in blocks + // need 20480 bits -> 3 blocks = 8192*3 bits + u16 s_firstdatazone = 220; // index of first data block + u16 s_log_zone_size = 0; // block size = 1024*2^s_log_zone_size + // = 1024*2^0 = 1024 + u32 s_max_size = 268966912; // max file size in bytes + // = (7+(1024/2)+(1024/2)^2)*1024 + u16 s_magic = 0x137F; // 0x137f Minix filesystem version 1 + u16 s_state = 1; // was the FS properly unmounted? +}; +``` + +[^1]: \scriptsize permet d'arrondir au prochain multiple de la taille d'un inode + +[//]: # ---------------------------------------------------------------- +## Exemple de superbloc + +```{.c .tiny} +struct minix_super_block { + u16 s_ninodes = 6848; // total number of inodes + u16 s_nzones = 20480; // total number of blocks + // = (20*1024^2)/1024 + u16 s_imap_blocks = 1; // inodes bitmap size in blocks + // need 6848 bits + // -> 1 block = 8192 bits + u16 s_zmap_blocks = 3; // data blocks bitmap size in blocks + // need 20480 bits -> 3 blocks = 8192*3 bits + u16 s_firstdatazone = 220; // index of first data block + u16 s_log_zone_size = 0; // block size = 1024*2^s_log_zone_size + // = 1024*2^0 = 1024 + u32 s_max_size = 268966912; // max file size in bytes + // = (7+(1024/2)+(1024/2)^2)*1024 + u16 s_magic = 0x137F; // 0x137f Minix filesystem version 1 + u16 s_state = 1; // was the FS properly unmounted? +}; +``` + +\centering +{ width=100% } + +[//]: # ---------------------------------------------------------------- +## Exemple d'inode - fichier répertoire + +Contenu de l'inode 1, la racine du FS + +\vspace{.2cm} + +```{.c .verysmall} +struct minix_inode { + u16 i_mode = 0x41ED; // 0x4 = directory + // 0x1ED = 755 in octal + // = rwx r-x r-x + u16 i_uid = 0; // 0 = root + u32 i_size = 256; // 256/16 = 16 dir_entry + u32 i_time = 1701436374; // seconds since 1/1/1970 + u8 i_gid = 0; // 0 = root + u8 i_nlinks = 8; // 8 dir entries point to + // this inode + u16 i_zone[7] = {220, 0, 0, 0, 0, 0, 0 }; // 1 data block + u16 i_indir_zone = 0; // no indirect block + u16 i_dbl_indir_zone = 0; // no double indirect block +}; +``` + +[//]: # ---------------------------------------------------------------- +## Exemple de bloc de données - contenu répertoire + +\footnotesize +1er bloc de données référencé par l'inode 1\ + +- bloc 220 (offset = 220*1024 = 0x37000) + +```{.tiny} +00037000 01 00 2E 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00037010 00 00 79 6F 00 00 00 00 00 00 00 00 00 00 00 00 ..yo............ +00037020 01 00 2E 2E 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00037030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00037040 02 00 72 6F 6F 74 00 00 00 00 00 00 00 00 00 00 ..root.......... +00037050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00037060 03 00 62 69 6E 00 00 00 00 00 00 00 00 00 00 00 ..bin........... +00037070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00037080 04 00 75 73 72 00 00 00 00 00 00 00 00 00 00 00 ..usr........... +00037090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +000370A0 0A 00 65 74 63 00 00 00 00 00 00 00 00 00 00 00 ..etc........... +000370B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +000370C0 0F 00 74 6D 70 00 00 00 00 00 00 00 00 00 00 00 ..tmp........... +000370D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +000370E0 32 00 64 65 76 00 00 00 00 00 00 00 00 00 00 00 2.dev........... +000370F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +``` + +\scriptsize +- Les noms `.` (0x2E) et `..` (0x2E2E) pointent sur l'inode 1 (la racine) +- 7 répertoires : `root`, `bin`, `usr`, `etc`, `tmp`, `dev` (inodes 1, 2, 3, 4, 0xA, 0xF, 0x32) +- 8 `dir_entry` inutilisées (inodes à 0) ; rappel : une entrée fait 16 bytes + +[//]: # ---------------------------------------------------------------- +## Exemple d'inode - fichier répertoire + +Contenu de l'inode 2, répertoire `/root` + +\vspace{.2cm} + +```{.c .verysmall} +struct minix_inode { + u16 i_mode = 0x41ED; // 0x4 = directory + // 0x1ED = 755 in octal + // = rwx r-x r-x + u16 i_uid = 0; // 0 = root + u32 i_size = 160; // 160/16 = 10 dir_entry + u32 i_time = 1701436512; // seconds since 1/1/1970 + u8 i_gid = 0; // 0 = root + u8 i_nlinks = 2; // 2 dir entries point to + // this inode + u16 i_zone[7] = {221, 0, 0, 0, 0, 0, 0 }; // 1 data block + u16 i_indir_zone = 0; // no indirect block + u16 i_dbl_indir_zone = 0; // no double indirect block +}; +``` + +[//]: # ---------------------------------------------------------------- +## Exemple de bloc de données - contenu répertoire + +\small +1er bloc de données référencé par l'inode 2\ + +- bloc 221 (offset = 221*1024 = 0x37400) + +\vspace{.2cm} + +```{.tiny} +00037400 02 00 2E 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00037410 6C 03 6C 69 6E 75 78 00 00 00 00 00 00 00 00 00 l.linux......... +00037420 01 00 2E 2E 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00037430 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00037440 09 00 73 79 73 74 65 6D 00 00 00 00 00 00 00 00 ..system........ +00037450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00037460 0B 00 68 65 6C 6C 6F 2E 63 00 00 00 00 00 00 00 ..hello.c....... +00037470 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00037480 0E 00 2E 62 61 73 68 5F 6C 6F 67 69 6E 00 00 00 ...bash_login... +00037490 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +``` + +\footnotesize +- Le nom `.` (0x2E) pointe sur l'inode 2 (lui même) +- Le nom `.` (0x2E2E) pointe sur le répertoire parent, l'inode 1 (la racine) +- Il y a 2 répertoires : `linux` (inode 0x36C) et `system` (inode 0x9) +- Il y a 2 fichiers : `hello.c` (inode 0xB) et `.bash_login` (inode 0xE) +- Il y a 4 `dir_entry` inutilisées (inodes à 0) + +[//]: # ---------------------------------------------------------------- +## Exemple d'inode - fichier régulier + +Contenu de l'inode 11 (0xB) + +\vspace{.2cm} + +```{.c .verysmall} +struct minix_inode { + u16 i_mode = 0x81A4; // 0x8 = regular file + // 0x1A4 = 644 in octal + // = rw- r-- r-- + u16 i_uid = 0; // 0 = root + u32 i_size = 63; // 1 data block (1 KB/block) + u32 i_time = 1426700385; // seconds since 1/1/1970 + u8 i_gid = 0; // 0 = root + u8 i_nlinks = 1; // 1 dir entry points to this inode + u16 i_zone[7] = { 583 0 0 0 0 0 0 }; // 1 data block + u16 i_indir_zone = 0; // no indirect block + u16 i_dbl_indir_zone = 0; // no double indirect block +}; +``` + +[//]: # ---------------------------------------------------------------- +## Exemple de bloc de données - contenu fichier régulier + +\small +Contenu du 1er bloc de données référencé par l'inode 11\ + +- bloc 583 (offset = 583*1024 = 0x91C00) + +\vspace{.2cm} + +```{.tiny} +00091C00 23 69 6E 63 6C 75 64 65 20 3C 73 74 64 69 6F 2E #include <stdio. +00091C10 68 3E 0A 0A 76 6F 69 64 20 6D 61 69 6E 28 29 0A h>..void main(). +00091C20 7B 0A 09 09 70 72 69 6E 74 66 28 22 48 65 6C 6C {...printf("Hell +00091C30 6F 20 57 6F 72 6C 64 5C 6E 22 29 3B 0A 7D 0A 00 o World\n");.}.. +00091C40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00091C50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00091C60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00091C70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00091C80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00091C90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00091CA0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00091CB0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00091CC0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00091CD0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +``` + +[//]: # ---------------------------------------------------------------- +## Exemple d'inode - fichier régulier + +Contenu de l'inode 16 + +\vspace{.2cm} + +```{.c .verysmall} +struct minix_inode { + u16 i_mode = 0x81C9; // 0x8 = regular file + // 0x1C9 = 711 in octal + // = rwx --x --x + u16 i_uid = 0; // 0 = root + u32 i_size = 283652; // 278 data blocks (1 KB/block) + u32 i_time = 1426700385; // seconds since 1/1/1970 + u8 i_gid = 0; // 0 = root + u8 i_nlinks = 2; // 2 dir entries point to this inode + u16 i_zone[7] = { 588 589 590 591 592 593 594 }; + // 7 data blocks + u16 i_indir_zone = 595; // block 595 contains 271 pointers + u16 i_dbl_indir_zone = 0; // no double indirect block +}; +``` + +[//]: # ---------------------------------------------------------------- +## Exemple de bloc de données - contenu fichier régulier + +\small +Contenu du bloc indirect référencé par l'inode 11\ + +- bloc 595 (offset = 595*1024 = 0x94C00) + +\vspace{.2cm} + +```{.tiny} +00094C00 54 02 55 02 56 02 57 02 58 02 59 02 5A 02 5B 02 T.U.V.W.X.Y.Z.[. +00094C10 5C 02 5D 02 5E 02 5F 02 60 02 61 02 62 02 63 02 \.].^._.`.a.b.c. +00094C20 64 02 65 02 66 02 67 02 68 02 69 02 6A 02 6B 02 d.e.f.g.h.i.j.k. +00094C30 6C 02 6D 02 6E 02 6F 02 70 02 71 02 72 02 73 02 l.m.n.o.p.q.r.s. +00094C40 74 02 75 02 76 02 77 02 78 02 79 02 7A 02 7B 02 t.u.v.w.x.y.z.{. +00094C50 7C 02 7D 02 7E 02 7F 02 80 02 81 02 82 02 83 02 |.}.~........... +00094C60 84 02 85 02 86 02 87 02 88 02 89 02 8A 02 8B 02 ................ +00094C70 8C 02 8D 02 8E 02 8F 02 90 02 91 02 92 02 93 02 ................ +00094C80 94 02 95 02 96 02 97 02 98 02 99 02 9A 02 9B 02 ................ +00094C90 9C 02 9D 02 9E 02 9F 02 A0 02 A1 02 A2 02 A3 02 ................ +00094CA0 A4 02 A5 02 A6 02 A7 02 A8 02 A9 02 AA 02 AB 02 ................ +... +``` + +- Prochains blocs de données : 0x254, 0x255, 0x256, 0x257, ... + +[//]: # ---------------------------------------------------------------- +## Important : inodes + +\small + +- Le nombre total d'inodes pouvant être créés dans le FS est indiqué par le champs `ninodes` du superbloc +- La table des inodes possède `ninodes` entrées +- Le premier inode de la table (à l'indice 0) est l'inode 1 + - \footnotesize il n'y a donc pas d'inode 0 ! +- **Attention** : le bit 0 du bitmap indique l'état de l'inode 0\ ! + - \footnotesize le bit 0 est toujours à 1 (utilisé), bien que l'inode 0 n'existe pas + - un FS vide aura donc 2 bits à 1 dans le bitmap\ : le bit 0 (inode 0) et le bit 1 (inode 1 = répertoire racine) + +En conséquence : + +\vspace{-.3cm} + +- Pour lire le contenu de l'inode `n`, il faut lire l'entrée à l'indice `(n-1)` dans la table des inodes +- Pour savoir si l'inode `n` est utilisé, il faut lire le bit à l'indice `n` dans le bitmap des inodes + +[//]: # ---------------------------------------------------------------- +## Important : blocs de données + +\small + +- Les n° de blocs dans l'inode sont relatifs au début du FS +- Le bitmap des blocs de données indique uniquement l'état des **blocs de données** utilisés (donc pas superbloc, bitmaps, etc.) +- **Attention** : le bit 0 du bitmap des blocs de données est à **ignorer**\ ! + - \footnotesize il est toujours à 1 et ne représente aucun bloc de données + - le bit 1 du bitmap correspond au bloc `firstdatazone` indiqué dans le superbloc + - il correspond donc au premier bloc de données + +En conséquence[^2] : + +\vspace{-.3cm} + +- Tout bloc n indiqué dans l'inode correspond à l'indice `(n-firstdatazone+1)` dans le bitmap des blocs de données +- Nombre total de blocs de données : `(nzones-firstdatazone)` + +[^2]: \scriptsize \texttt{firstdatazone} et \texttt{nzones} sont les champs du même nom dans le superbloc + +<!-- + - où `firstdatazone` est le champs du même nom dans le superbloc (= nombre de blocs utilisés par\ : superbloc + bitmaps + table d'inodes) + + + - \footnotesize si le premier bloc de données est le bloc 110, celui-ci correspond au bit 1 dans le bitmap + - le bit 3 du bitmap correspond donc au bloc 113, etc. +--> + +[//]: # ---------------------------------------------------------------- +## Rappel : *endianness* (1/2) + +- L'*endianness* défini la manière dont les entiers sont stockés en mémoire + +\vspace{.2cm} +- ***Big-endian*** + - le byte le plus significatif (d'un mot) est stocké à l'adresse la plus basse + - le byte le moins significatif est stocké à l'adresse la plus haute + +\vspace{.2cm} +- ***Little-endian*** + - le byte le plus significatif (d'un mot) est stocké à l'adresse la plus haute + - le byte le moins significatif est stocké à l'adresse la plus basse + +[//]: # ---------------------------------------------------------------- +## Rappel : *endianness* (2/2) + +Exemple de valeurs 8 bits, 16 bits et 32 bits, en représentation hexadécimale, où les adresses "grandissent" de gauche à droite : + +\vspace{.3cm} +\small + +**Taille de mot** **Valeur** **Big-endian** **Little-endian** +----------------- ----------- -------------- ----------------- +8 bits (1 byte) `4c` `4c` `4c` +16 bits (2 bytes) `4c3f` `4c 3f` `3f 4c` +32 bits (4 bytes) `4c3f85ed` `4c 3f 85 ed` `ed 85 3f 4c` + +[//]: # ---------------------------------------------------------------- +## Sérialisation/déserialisation de structure + +- **Sérialisation** de structure = écriture, en une opération, d'une structure sur un fichier, un socket, un pipe, etc. + - typiquement via un appel à `write` ou `fwrite` + +\vspace{.3cm} + +- **Déserialisation** de structure = lecture, en une opération, depuis un fichier, un socket, un pipe, etc. dans une structure + - typiquement via un appel à `read` ou `fread` + +[//]: # ---------------------------------------------------------------- +## Danger avec la sérialisation/déserialisation + +```{.c .tiny} +struct st1 { struct __attribute__ ((__packed__)) st2 { + uint8_t tab[7]; uint8_t tab[7]; + uint16_t n; uint16_t n; + uint32_t big; uint32_t big; + uint8_t x; uint8_t x; + uint8_t y; uint8_t y; +}; }; + +int main() { + printf("%ld %ld\n", sizeof(struct st1), sizeof(struct st2)); + return 0; +} +``` + +::: incremental +- Affichage ? + - **`20 15`** +- Pourquoi ? +- Conséquence : **\textcolor{myred}{toujours}** utiliser l'attribut `__packed__` sur les structures sérialisées\ ! +::: + +[//]: # ---------------------------------------------------------------- +## Ressources + +\small + +- `mkfs.minix` source code\ +\footnotesize [\textcolor{myblue}{https://github.com/util-linux/util-linux/blob/master/disk-utils/mkfs.minix.c}](https://github.com/util-linux/util-linux/blob/master/disk-utils/mkfs.minix.c) + +\small + +- `minix-fs` on-disk structures\ +\footnotesize [\textcolor{myblue}{https://github.com/util-linux/util-linux/blob/master/include/minix.h}](https://github.com/util-linux/util-linux/blob/master/include/minix.h) diff --git a/9.filesystems/05_Systemes_fichiers_implementation.md b/9.filesystems/05_Systemes_fichiers_implementation.md new file mode 100644 index 0000000000000000000000000000000000000000..981a1faded7bbeefaa93a80efb5c6babe94f31b5 --- /dev/null +++ b/9.filesystems/05_Systemes_fichiers_implementation.md @@ -0,0 +1,356 @@ +--- +author: Florent Gluck - Florent.Gluck@hesge.ch + +title: Systèmes de fichiers - Implémentation + +date: \vspace{.5cm} \footnotesize \today + +institute: \vspace{0.5cm} \tiny \textsuperscript{*}Remerciements à Mickaël Hoerdt + +pandoc-latex-fontsize: + - classes: [tiny] + size: tiny + - classes: [verysmall] + size: scriptsize + - classes: [small] + size: footnotesize + - classes: [huge, important] + size: huge +--- + +## TODO + +- Ajouter suppression d'un fichier + - méthode rapide : seul le bitmap des inode et des blocs est modifié + - méthode sécurisée : les blocs de données et le contenus des inodes sont également effacés + +[//]: # ---------------------------------------------------------------- +# Adressage des blocs de données + + +[//]: # ---------------------------------------------------------------- +## Facilité d'adressage + +On désire obtenir un accès ordonné aux blocs qui composent le contenu d'un fichier : début du fichier en bloc 0, suite en bloc 1, etc. + +\vspace{.5cm} + +\centering +{ width=60% } + +[//]: # ---------------------------------------------------------------- +## Adressage : problème 1 + +Les blocs de données d'un fichier ne sont pas toujours contigus sur le disque + +\centering +{ width=100% } + + +[//]: # ---------------------------------------------------------------- +## Adressage souhaité + +On désire une fonction `bmap` qui mappe un numéro de bloc du fichier (0, 1, 2, ...) vers un numéro de bloc du disque : + +\vspace{.2cm} + +```{.c .small} +// i : numero du bloc (logique) du fichier +// renvoie le numero du bloc physique sur disque +int bmap(inode, i); +``` + +\centering +{ width=50% } + +\footnotesize + +- `bmap(inode, 0)` $\rightarrow$ 18 +- `bmap(inode, 1)` $\rightarrow$ 20 +- `bmap(inode, 2)` $\rightarrow$ 25 +- `bmap(inode, 3)` $\rightarrow$ 11 + +[//]: # ---------------------------------------------------------------- +## Adressage : problème 2 + +Certains blocs peuvent être des blocs indirects, c'est à dire contenir les adresses d'autres blocs + +\vspace{.2cm} + +\centering +{ width=100% } + +[//]: # ---------------------------------------------------------------- +## Problème des indirections + +\footnotesize + +- Selon le même principe, on peut ajouter des blocs doublement, triplement, etc. indirects +- La distinction entre bloc simple, bloc indirect et bloc double indirect se fait sur sa position dans le tableau des adresses de l'inode + +\centering +{ width=90% } + +[//]: # ---------------------------------------------------------------- +## Repenser la structure de données + +Ainsi la structure des inodes de MINIX : + +```{.c .verysmall} +struct minix_inode { + ... + + u16 i_zone[7]; // direct pointers + u16 i_indir_zone; // indirect pointer + u16 i_dbl_indir_zone; // double indirect pointer +}; +``` + +peut s'écrire : + +```{.c .verysmall} +struct minix_inode { + ... + + u16 i_zone[9]; // i_zone[7] = indirect pointers + // i_zone[8] = double indirect pointers +}; +``` + +[//]: # ---------------------------------------------------------------- +## Fonction bmap : algorithme (1/2) + +```{.c .tiny} +// i : numero du bloc (logique) du fichier +// renvoie le numero du bloc physique sur disque +int bmap(inode, i); +``` + +\small +Pseudo-code avec 2 niveaux d'indirections : + +```{.c .tiny} +if (i < nb_blocs_adressables_directement) { // cas 1 + return inode.i_zone[i] +} + +i = i-nb_blocs_adressables_directement + +if (i < nb_blocs_adressables_avec_une_seule_indir) { // cas 2 + indir_bloc = read_block(inode.i_zone[indice_du_bloc_des_indir_simples]) + return indir_bloc[i] +} + +i = i-nb_blocs_adressables_avec_une_seule_indir + +if (i < nb_blocs_adressables_avec_une_double_indir) { // cas 3 + indir_bloc = read_block(inode.i_zone[indice_du_bloc_des_indir_doubles]) + indir2_bloc = read_block( + indir_bloc[i/nb_blocs_adressables_avec_une_seule_indir]) + return indir2_bloc[i % nb_blocs_adressables_avec_une_seule_indir] +} +``` + +[//]: # ---------------------------------------------------------------- +## Fonction bmap : algorithme (2/2) + +- Pourquoi la soustraction entre chaque cas ? + - pour réajuster l'indice dans le bloc lors d'une indirection : on passe d'un indice absolu à un indice relatif au bloc indirect + +\vspace{.2cm} + +- Exemple : si 7 blocs sont adressables directement, mais qu'on veut le 8ème, on veut le premier indice du bloc +indirect, pas l'indice 8 + +[//]: # ---------------------------------------------------------------- +## Fonction bmap : exemple (1/4) + +\footnotesize + +- Nombre de blocs adressables directement : 2 +- Nombre de blocs adressables avec une seule indirection : 4 +- Nombre de blocs adressables avec une double indirection : 4*4 + +\centering +{ width=90% } + +[//]: # ---------------------------------------------------------------- +## Fonction bmap : exemple (2/4) + +```{.c .tiny} +if (i < 2) { // cas 1 + return inode.i_zone[i] +} + +i = i-2 + +if (i < 4) { // cas 2 + indir_bloc = read_block(inode.i_zone[indice_du_bloc_des_indir_simples]) + return indir_bloc[i] +} + +i = i-4 + +if (i < 16) { // cas 3 + indir_bloc = read_block(inode.i_zone[indice_du_bloc_des_indir_doubles]) + indir2_bloc = read_block(indir_bloc[i/4]) + return indir2_bloc[i % 4] +} +``` + +[//]: # ---------------------------------------------------------------- +## Fonction bmap : exemple (3/4) + +\scriptsize + +**i = 4** : + +- pas à inférieur à **2** $\rightarrow$ on rejette le cas 1 +- 4-**2** = **\textcolor{mygreen}{2}** +- **\textcolor{mygreen}{2}** inférieur à **4** $\rightarrow$ on entre dans le cas 2 +- lecture du bloc d'indirection simple +- indice **\textcolor{mygreen}{2}** dans bloc d'indirection simple pointe bien vers bloc 4 + +**i = 6** : + +- pas inférieur à **2** $\rightarrow$ on rejette le cas 1 +- 6-**2** = **\textcolor{mygreen}{4}** +- **\textcolor{mygreen}{4}** pas inférieur à **4** $\rightarrow$ on rejette le cas 2 +- **\textcolor{mygreen}{4}**-**4** = **\textcolor{myred}{0}** +- **\textcolor{myred}{0}** inférieur à **16** $\rightarrow$ on entre dans le cas 3 +- lecture du bloc d'indirection simple d'indice **\textcolor{myred}{0}**/**4** = 0 + - \scriptsize indice **\textcolor{myred}{0}** % **4** (0) dans bloc d'indirection simple pointe bien vers bloc 6 + +[//]: # ---------------------------------------------------------------- +## Fonction bmap : exemple (4/4) + +\scriptsize + +**i = 9** : + +- pas inférieur à **2** $\rightarrow$ on rejette le cas 1 +- 9-**2** = **\textcolor{mygreen}{7}** +- **\textcolor{mygreen}{7}** pas inférieur à **4** $\rightarrow$ on rejette le cas 2 +- **\textcolor{mygreen}{7}**-4 = **\textcolor{myred}{3}** +- **\textcolor{myred}{3}** inférieur à **16** $\rightarrow$ on entre dans le cas 3 +- lecture du bloc d'indirection simple d'indice **\textcolor{myred}{3}**/**4** = 0 + - \scriptsize indice **\textcolor{myred}{3}** % **4** (3) dans bloc d'indirection simple pointe bien vers bloc 9 + +**i = 10** : + +- pas inférieur à **2** $\rightarrow$ on rejette le cas 1 +- 10-**2** = **\textcolor{myred}{8}** +- **\textcolor{myred}{8}** pas inférieur à **4** $\rightarrow$ on rejette le cas 2 +- **\textcolor{myred}{8}**-**4** = **\textcolor{myred}{4}** +- **\textcolor{myred}{4}** inférieur à **16** $\rightarrow$ on entre dans le cas 3 +- lecture du bloc d'indirection simple d'indice **\textcolor{myred}{4}**/**4** = 1 + - \scriptsize indice **\textcolor{myred}{4}** % **4** (0) dans bloc d'indirection simple pointe bien vers bloc 10 + +[//]: # ---------------------------------------------------------------- +# Résolution du chemin d'accès + +[//]: # ---------------------------------------------------------------- +## Problème du chemin d'accès + +- Les inodes n'ont pas de noms, juste un numéro... + +\vspace{.5cm} + +- Comment retrouver le numéro d'un inode à partir de son chemin d'accès dans la chaîne des répertoires du système de fichiers ? + +[//]: # ---------------------------------------------------------------- +## Fonction namei + +On désire une fonction `namei` qui retourne le numéro d'un inode à partir de son chemin d'accès dans le système de fichiers : + +\vspace{.2cm} + +```{.c .small} +// renvoie le numero d'inode du fichier dont le +// chemin d'acces est path +int namei(path); +``` + +- La recherche débute depuis : + - l'inode de la racine si le chemin d'accès est absolu + - le répertoire courant du processus si le chemin d'accès est relatif +- `namei` est typiquement utilisée par tous les appels systèmes qui prennent un chemin d'accès en argument + +[//]: # ---------------------------------------------------------------- +## Fonction namei : example + +P.ex. appeler `namei` sur le chemin `"/usr/bin/bash"` parcourt le contenu des inodes suivants et renvoie 21 : + +\vspace{.3cm} + +\centering +{ width=100% } + +[//]: # ---------------------------------------------------------------- +## Fonction namei : algorithme + +Pseudo-code pour un chemin absolu : + +\vspace{.2cm} + +```{.c .small} +int namei(path) { + inode = ROOT_INODE + pour chaque composant du path p { + inode = lookup_entry(inode, p) + } + return inode +} +``` + +[//]: # ---------------------------------------------------------------- +## Fonction lookup_entry + +\small +\vspace{.2cm} + +```{.c .small} +// renvoie le numero d'inode correspondant a name +int lookup_entry(dir_inode, name); +``` + +- La fonction `lookup_entry` recherche un fichier dans un répertoire et renvoie son inode +- `lookup_entry` réalise une recherche linéaire de la chaîne de caractères `name` dans les entrées de répertoire (`dir_entry`) du répertoire dont l'inode est `dir_inode` : + +**Attention** : + +- Le contenu du répertoire peut-être réparti sur plusieurs blocs $\rightarrow$ utiliser `bmap` +- Aucune garantie que la taille du répertoire soit un multiple de la taille des blocs : utiliser le champs taille de l'inode pour limiter la recherche + +[//]: # ---------------------------------------------------------------- +## Fonction lookup_entry : algorithme + +Pseudo-code : + +\vspace{.2cm} + +```{.c .small} +int lookup_entry(dir_inode, name) { + pour chaque bloc de dir_node et dans la limite + de dir_inode.size { + if (dir_entry.name == name) { + return dir_entry.inode + } + } + return not_found +} +``` + +[//]: # ---------------------------------------------------------------- +## Fonction del_entry + +\small + +```{.c} +del_entry(dir_inode, name) +``` + +- La fonction `del_entry` supprime un fichier d'un répertoire +- `del_entry` réalise une recherche linéaire de la chaîne de caractères `name` dans les entrées de répertoire (`dir_entry`) du répertoire dont l'inode est `dir_inode` : +- Attention : tout comme pour `lookup_entry`, le contenu du répertoire peut-être réparti sur plusieurs blocs +- Une fois l'entrée de répertoire (`dir_entry`) trouvée, son champs inode est mis à zéro et le bloc modifié est écrit sur disque diff --git a/9.filesystems/images/FAT_alloc.png b/9.filesystems/images/FAT_alloc.png new file mode 100644 index 0000000000000000000000000000000000000000..0c2154653e772f9787f40af13b7677e28b8a9fe8 Binary files /dev/null and b/9.filesystems/images/FAT_alloc.png differ diff --git a/9.filesystems/images/FAT_disk_layout.png b/9.filesystems/images/FAT_disk_layout.png new file mode 100644 index 0000000000000000000000000000000000000000..f46d128717e2f82a70f92550571e84e74f723210 Binary files /dev/null and b/9.filesystems/images/FAT_disk_layout.png differ diff --git a/9.filesystems/images/addressing.png b/9.filesystems/images/addressing.png new file mode 100644 index 0000000000000000000000000000000000000000..cfb7576afe2bfe7adcf26b3aa9a894bdf3b5abac Binary files /dev/null and b/9.filesystems/images/addressing.png differ diff --git a/9.filesystems/images/addressing_example.png b/9.filesystems/images/addressing_example.png new file mode 100644 index 0000000000000000000000000000000000000000..92b1c6b796c1602ec5aaf73f84e4f6f4bb7bbc7f Binary files /dev/null and b/9.filesystems/images/addressing_example.png differ diff --git a/9.filesystems/images/block_and_cluster.png b/9.filesystems/images/block_and_cluster.png new file mode 100644 index 0000000000000000000000000000000000000000..d7ba9e7d3aa917eaa54180fb5338f8599291ec8b Binary files /dev/null and b/9.filesystems/images/block_and_cluster.png differ diff --git a/9.filesystems/images/blocks_addr_problem.png b/9.filesystems/images/blocks_addr_problem.png new file mode 100644 index 0000000000000000000000000000000000000000..5faf7317ed4f0fc6644199ccb057fa833c4afb18 Binary files /dev/null and b/9.filesystems/images/blocks_addr_problem.png differ diff --git a/9.filesystems/images/blocks_addr_problem2.png b/9.filesystems/images/blocks_addr_problem2.png new file mode 100644 index 0000000000000000000000000000000000000000..d1500d971c3978df6492b45fc8b9eef45ac5ea37 Binary files /dev/null and b/9.filesystems/images/blocks_addr_problem2.png differ diff --git a/9.filesystems/images/blocks_indirections.png b/9.filesystems/images/blocks_indirections.png new file mode 100644 index 0000000000000000000000000000000000000000..b7581087504dd6a6d1e9777ed826fbbbd6c099f1 Binary files /dev/null and b/9.filesystems/images/blocks_indirections.png differ diff --git a/9.filesystems/images/blocks_simple_addr.png b/9.filesystems/images/blocks_simple_addr.png new file mode 100644 index 0000000000000000000000000000000000000000..f539cd7e1a71ec12a7ebcef4ea417e5d80bbffdf Binary files /dev/null and b/9.filesystems/images/blocks_simple_addr.png differ diff --git a/9.filesystems/images/bmap.png b/9.filesystems/images/bmap.png new file mode 100644 index 0000000000000000000000000000000000000000..31d0acac873c164035e7e5ff10f95bf615e40368 Binary files /dev/null and b/9.filesystems/images/bmap.png differ diff --git a/9.filesystems/images/bmap_example.png b/9.filesystems/images/bmap_example.png new file mode 100644 index 0000000000000000000000000000000000000000..53216e7acc61765d1d2353a627e34cbf296f16bc Binary files /dev/null and b/9.filesystems/images/bmap_example.png differ diff --git a/9.filesystems/images/contiguous_alloc.png b/9.filesystems/images/contiguous_alloc.png new file mode 100644 index 0000000000000000000000000000000000000000..b06ced53a1930dd6e32019e0ebed7dd35f912f45 Binary files /dev/null and b/9.filesystems/images/contiguous_alloc.png differ diff --git a/9.filesystems/images/dir_content.png b/9.filesystems/images/dir_content.png new file mode 100644 index 0000000000000000000000000000000000000000..43253b3f2d343711f544491b9eb4ebb89ba04d0c Binary files /dev/null and b/9.filesystems/images/dir_content.png differ diff --git a/9.filesystems/images/external_fragmentation.png b/9.filesystems/images/external_fragmentation.png new file mode 100644 index 0000000000000000000000000000000000000000..36462cd4defbfa9165a3b9bb3898c434a3801fb8 Binary files /dev/null and b/9.filesystems/images/external_fragmentation.png differ diff --git a/9.filesystems/images/hdd.png b/9.filesystems/images/hdd.png new file mode 100644 index 0000000000000000000000000000000000000000..4a28e5afe52938ce78ed0e2d6e4696b656ead2cb Binary files /dev/null and b/9.filesystems/images/hdd.png differ diff --git a/9.filesystems/images/indexed_alloc.png b/9.filesystems/images/indexed_alloc.png new file mode 100644 index 0000000000000000000000000000000000000000..0dea632d63264ca1cc64bfda61027f04495b1e5e Binary files /dev/null and b/9.filesystems/images/indexed_alloc.png differ diff --git a/9.filesystems/images/inodes_table.png b/9.filesystems/images/inodes_table.png new file mode 100644 index 0000000000000000000000000000000000000000..2fe07823352e71017603ddbf6bc132e09bad9533 Binary files /dev/null and b/9.filesystems/images/inodes_table.png differ diff --git a/9.filesystems/images/internal_fragmentation.png b/9.filesystems/images/internal_fragmentation.png new file mode 100644 index 0000000000000000000000000000000000000000..91d2e519240ee6c25ae09ca0151c4969b471efbe Binary files /dev/null and b/9.filesystems/images/internal_fragmentation.png differ diff --git a/9.filesystems/images/linked_list.png b/9.filesystems/images/linked_list.png new file mode 100644 index 0000000000000000000000000000000000000000..05b3035b40ed305046ae70bf6d0c412740b30c72 Binary files /dev/null and b/9.filesystems/images/linked_list.png differ diff --git a/9.filesystems/images/linked_list_alloc.png b/9.filesystems/images/linked_list_alloc.png new file mode 100644 index 0000000000000000000000000000000000000000..22086ecbc8671a57d8b55b0da122e5bfba1948dd Binary files /dev/null and b/9.filesystems/images/linked_list_alloc.png differ diff --git a/9.filesystems/images/minix_example.png b/9.filesystems/images/minix_example.png new file mode 100644 index 0000000000000000000000000000000000000000..bc5b97eb93d27308eaba5c11f37120a72f51d001 Binary files /dev/null and b/9.filesystems/images/minix_example.png differ diff --git a/9.filesystems/images/minix_gen_struct.png b/9.filesystems/images/minix_gen_struct.png new file mode 100644 index 0000000000000000000000000000000000000000..2e59bd492d96e9e14c7977f849734cc361c5add1 Binary files /dev/null and b/9.filesystems/images/minix_gen_struct.png differ diff --git a/9.filesystems/images/multi_indexed_alloc.png b/9.filesystems/images/multi_indexed_alloc.png new file mode 100644 index 0000000000000000000000000000000000000000..4663d554c14d63966295ea90a6de40ed25653898 Binary files /dev/null and b/9.filesystems/images/multi_indexed_alloc.png differ diff --git a/9.filesystems/images/namei_example.png b/9.filesystems/images/namei_example.png new file mode 100644 index 0000000000000000000000000000000000000000..e2c0674c51b5201cb66ef6066a97c2a135752acc Binary files /dev/null and b/9.filesystems/images/namei_example.png differ diff --git a/9.filesystems/images/sectors.png b/9.filesystems/images/sectors.png new file mode 100644 index 0000000000000000000000000000000000000000..7dc75bff7b3ed5e75b63d3340679a74b6328050d Binary files /dev/null and b/9.filesystems/images/sectors.png differ diff --git a/9.filesystems/images/simple_fs1.png b/9.filesystems/images/simple_fs1.png new file mode 100644 index 0000000000000000000000000000000000000000..b888ac10e6caef623d720076d1cb80967439d2d4 Binary files /dev/null and b/9.filesystems/images/simple_fs1.png differ diff --git a/9.filesystems/images/simple_fs2.png b/9.filesystems/images/simple_fs2.png new file mode 100644 index 0000000000000000000000000000000000000000..76d568a77b11ac42910db6efb60ddca7eaa9fdac Binary files /dev/null and b/9.filesystems/images/simple_fs2.png differ diff --git a/9.filesystems/images/simple_fs3.png b/9.filesystems/images/simple_fs3.png new file mode 100644 index 0000000000000000000000000000000000000000..a1e9b39e0f93695ab2bc53e44fc239015e40fdf2 Binary files /dev/null and b/9.filesystems/images/simple_fs3.png differ diff --git a/9.filesystems/images/simple_fs4.png b/9.filesystems/images/simple_fs4.png new file mode 100644 index 0000000000000000000000000000000000000000..63828e43292a887398cbd071f2f2e2eb311c300d Binary files /dev/null and b/9.filesystems/images/simple_fs4.png differ diff --git a/9.filesystems/images/simple_fs5.png b/9.filesystems/images/simple_fs5.png new file mode 100644 index 0000000000000000000000000000000000000000..f80de204debf989df6eda962bd3b835be02de4b6 Binary files /dev/null and b/9.filesystems/images/simple_fs5.png differ diff --git a/9.filesystems/images/simple_fs6.png b/9.filesystems/images/simple_fs6.png new file mode 100644 index 0000000000000000000000000000000000000000..4388b9165e51086fba3a44d1406bd7bf62a27b85 Binary files /dev/null and b/9.filesystems/images/simple_fs6.png differ diff --git a/9.filesystems/images/simple_fs7.png b/9.filesystems/images/simple_fs7.png new file mode 100644 index 0000000000000000000000000000000000000000..9e4c16a0b83cecf24c09e31b2d5cc2d094bfe606 Binary files /dev/null and b/9.filesystems/images/simple_fs7.png differ diff --git a/9.filesystems/images/simple_fs8.png b/9.filesystems/images/simple_fs8.png new file mode 100644 index 0000000000000000000000000000000000000000..df4e1215d7582f76cf29ca5802119d943ab351cd Binary files /dev/null and b/9.filesystems/images/simple_fs8.png differ diff --git a/9.filesystems/index.html b/9.filesystems/index.html new file mode 100644 index 0000000000000000000000000000000000000000..3e81c030b0aaf3dc87d34301c15fa009bba754db --- /dev/null +++ b/9.filesystems/index.html @@ -0,0 +1,58 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <meta name="generator" content="pandoc"> + <meta name="author" content="Guillaume Chanel"> + <title>Drivers et modules</title> + <meta name="apple-mobile-web-app-capable" content="yes"> + <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> + <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui"> + + <link rel="stylesheet" href="../../../dist/reset.css"> + <link rel="stylesheet" href="../../../dist/reveal.css"> + <link rel="stylesheet" href="../../../dist/theme/white.css" id="theme"> + + <!-- Higlight theme with a fallback on local monokai in case of connexion pb --> + <!-- TODO: the monokai fallback cannot be included has it conflicts on the struct keyword with other themes + check another way to make a fallback --> + <!-- <link rel="stylesheet" href="../../../plugin/highlight/monokai.css" id="highlight-theme"> --> + <link rel="stylesheet" href="https://highlightjs.org/static/demo/styles/googlecode.css" id="highlight-theme"> + + <!-- Add my own theme on top of classical reveal.js theme --> + <link rel="stylesheet" href="../css/mytheme.css"> + + <!-- Printing and PDF exports --> + <script> + var link = document.createElement('link'); + link.rel = 'stylesheet'; + link.type = 'text/css'; + link.href = window.location.search.match(/print-pdf/gi) ? '../../../css/print/pdf.css' : '../../../css/print/paper.css'; + document.getElementsByTagName('head')[0].appendChild(link); + </script> + <!--[if lt IE 9]> + <script src="../../../lib/js/html5shiv.js"></script> + <![endif]--> + + +<body> + <div class="reveal"> + <div class="slides"> + <section data-markdown="01_Systemes_fichiers_intro.md" data-separator-vertical="^\r?\n--\r?\n$"></section> + <section data-markdown="02_Systemes_fichiers_strategies_alloc.md" data-separator-vertical="^\r?\n--\r?\n$"></section> + <section data-markdown="03_Systemes_fichiers_struct_disque.md" data-separator-vertical="^\r?\n--\r?\n$"></section> + <section data-markdown="04_Systemes_fichiers_minix.md" data-separator-vertical="^\r?\n--\r?\n$"></section> + <section data-markdown="05_Systemes_fichiers_implementation.md" data-separator-vertical="^\r?\n--\r?\n$"></section> + </div> + </div> + + <script src="../../../js/reveal.js"></script> + + <!-- Initialize reveal.js with common configuration --> + <!-- TODO find a way to have chalkboard script included from the config to avoid redundancy in each presentation --> + <script src="../../../plugin/reveal.js-plugins/chalkboard/plugin.js"></script> + <script src="../config.js" type="module"></script> +</body> + +</html> \ No newline at end of file