Skip to content
Snippets Groups Projects
Commit 4cf076a7 authored by Guillaume Chanel's avatar Guillaume Chanel
Browse files

Add Florent's content without reformating

parent 640682a0
Branches
No related tags found
No related merge requests found
Showing
with 1862 additions and 0 deletions
---
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%"}
![](images/hdd.png){ 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
![](images/IBM-305-RAMAC.jpg){ 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
![](images/sectors.png){ 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
![](images/block_and_cluster.png){ 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
![](images/addressing.png){ 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
![](images/addressing_example.png){ 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
---
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
![](images/internal_fragmentation.png){ 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
![](images/external_fragmentation.png){ 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
![](images/contiguous_alloc.png){ 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}
![](images/linked_list.png){ width=70% }
\vspace{.3cm}
[//]: # ----------------------------------------------------------------
## 2 | Allocation par liste chaînée : exemple
\centering
![](images/linked_list_alloc.png){ 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}
![](images/FAT_disk_layout.png){ width=100% }
:::
::::::
[//]: # ----------------------------------------------------------------
## 2b | Contenu de la FAT : exemple
\centering
![](images/FAT_alloc.png){ 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
![](images/indexed_alloc.png){ 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
![](images/multi_indexed_alloc.png){ 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
---
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
![](images/simple_fs1.png){ 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
![](images/simple_fs2.png){ 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
![](images/simple_fs3.png){ 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
![](images/simple_fs4.png){ 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
![](images/simple_fs5.png){ 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
![](images/simple_fs6.png){ 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
![](images/inodes_table.png){ 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
![](images/multi_indexed_alloc.png){ 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
![](images/dir_content.png){ 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
![](images/simple_fs7.png){ 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
![](images/simple_fs8.png){ 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)
This diff is collapsed.
---
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
![](images/blocks_simple_addr.png){ width=60% }
[//]: # ----------------------------------------------------------------
## Adressage : problème 1
Les blocs de données d'un fichier ne sont pas toujours contigus sur le disque
\centering
![](images/blocks_addr_problem.png){ 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
![](images/bmap.png){ 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
![](images/blocks_addr_problem2.png){ 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
![](images/blocks_indirections.png){ 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
![](images/bmap_example.png){ 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
![](images/namei_example.png){ 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
9.filesystems/images/FAT_alloc.png

122 KiB

9.filesystems/images/FAT_disk_layout.png

64.1 KiB

9.filesystems/images/addressing.png

16.3 KiB

9.filesystems/images/addressing_example.png

25.8 KiB

9.filesystems/images/block_and_cluster.png

42.8 KiB

9.filesystems/images/blocks_addr_problem.png

92.4 KiB

9.filesystems/images/blocks_addr_problem2.png

89.8 KiB

9.filesystems/images/blocks_indirections.png

170 KiB

9.filesystems/images/blocks_simple_addr.png

12 KiB

9.filesystems/images/bmap.png

49.3 KiB

9.filesystems/images/bmap_example.png

173 KiB

9.filesystems/images/contiguous_alloc.png

1.05 MiB

9.filesystems/images/dir_content.png

116 KiB

9.filesystems/images/external_fragmentation.png

45.4 KiB

9.filesystems/images/hdd.png

352 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment