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

Finalize part 4 on file systems: minix

parent f93b3b12
No related branches found
No related tags found
No related merge requests found
......@@ -101,14 +101,11 @@ struct minix_inode {
Format du champs `i_mode` (16 bits) de l'inode :
Bits | Description | t
<div style="font-size:0.8em">
Bits | Description ||
----------------| -------------------------- |---------------------------
`12-15` | Type de fichier : |`0x1` : named pipe (FIFO)
`` | a |`0x2` : char device
b | b |`0x4` : directory
c | c |`0x6` : block device
d | d |`0x8` : regular file
we | e |`0xA` : symbolic link
`12-15` | Type de fichier |`0x1` : named pipe (FIFO)<br>`0x2` : char device<br>`0x4` : directory<br>`0x6` : block device<br>`0x8` : regular file<br>`0xA` : symbolic link
`11` | SUID bit |
`10` | SGID bit |
`9` | Sticky bit |
......@@ -116,15 +113,16 @@ Bits | Description | t
`3-5` | group permissions (rwx) |
`0-2` | others permissions (rwx) |
</div>
--
## Structure des entrées de répertoires
Structure d'une entrée de répertoire dans MINIX-fs v1.0 :
\vspace{.2cm}
```{.c .verysmall}
```c
// Variante : superblock magic 0x137F
#define MINIX_NAME_LEN 14
......@@ -134,7 +132,8 @@ struct minix_dir_entry {
};
```
- Taille d'un `dir_entry` en bytes ?
- Taille d'un `dir_entry` en bytes ? \
`$14*sizeof(char) + 2$ bytes ($16$ bits) $= 16$ bytes si $sizeof(char)=1$ byte` <!-- .element class="fragment" -->
--
......@@ -142,9 +141,7 @@ struct minix_dir_entry {
Structure du superbloc dans MINIX-fs v1.0 :
\vspace{.2cm}
```{.c .tiny}
```c
struct minix_super_block {
u16 s_ninodes; // total number of inodes
u16 s_nzones; // total number of blocks (including superblock)
......@@ -159,19 +156,19 @@ struct minix_super_block {
};
```
- Taille du superbloc en bytes ?
- Taille du superbloc en bytes ? \
`$20$ bytes` <!-- .element class="fragment" -->
--
## 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]
`$\rightarrow$ fs_blocks` = nombre de blocs au total
- Nombre inodes = `(fs_blocks/3 + 32) & 0xFFFFFFE0`<sup>1</sup>
\vspace{.2cm}
```{.c .tiny}
```c
struct minix_super_block {
u16 s_ninodes = 6848; // total number of inodes
u16 s_nzones = 20480; // total number of blocks
......@@ -190,14 +187,15 @@ struct minix_super_block {
u16 s_state = 1; // was the FS properly unmounted?
};
```
<!-- .element style="font-size:0.5em" -->
[^1]: \scriptsize permet d'arrondir au prochain multiple de la taille d'un inode
<small>1: permet d'arrondir au prochain multiple de la taille d'un inode</small>
--
## Exemple de superbloc
```{.c .tiny}
```c
struct minix_super_block {
u16 s_ninodes = 6848; // total number of inodes
u16 s_nzones = 20480; // total number of blocks
......@@ -216,9 +214,10 @@ struct minix_super_block {
u16 s_state = 1; // was the FS properly unmounted?
};
```
<!-- .element style="font-size:0.5em" -->
\centering
![](images/minix_example.png){ width=100% }
![](images/minix_example.png)
--
......@@ -226,9 +225,7 @@ struct minix_super_block {
Contenu de l'inode 1, la racine du FS
\vspace{.2cm}
```{.c .verysmall}
```c
struct minix_inode {
u16 i_mode = 0x41ED; // 0x4 = directory
// 0x1ED = 755 in octal
......@@ -249,12 +246,11 @@ struct minix_inode {
## Exemple de bloc de données - contenu répertoire
\footnotesize
1er bloc de données référencé par l'inode 1\
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 ................
......@@ -272,21 +268,23 @@ struct minix_inode {
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 ................
```
<!-- .element style="font-size:0.4em" -->
<div style="font-size: 0.8em">
\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
</div>
--
## Exemple d'inode - fichier répertoire
Contenu de l'inode 2, répertoire `/root`
\vspace{.2cm}
```{.c .verysmall}
```c
struct minix_inode {
u16 i_mode = 0x41ED; // 0x4 = directory
// 0x1ED = 755 in octal
......@@ -307,14 +305,11 @@ struct minix_inode {
## Exemple de bloc de données - contenu répertoire
\small
1er bloc de données référencé par l'inode 2\
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 ................
......@@ -326,23 +321,25 @@ struct minix_inode {
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 ................
```
<!-- .element style="font-size:0.5em" -->
<div style="font-size: 0.8em">
\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)
</div>
--
## Exemple d'inode - fichier régulier
Contenu de l'inode 11 (0xB)
\vspace{.2cm}
```{.c .verysmall}
```c
struct minix_inode {
u16 i_mode = 0x81A4; // 0x8 = regular file
// 0x1A4 = 644 in octal
......@@ -362,14 +359,11 @@ struct minix_inode {
## 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
......@@ -392,9 +386,7 @@ Contenu du 1er bloc de données référencé par l'inode 11\
Contenu de l'inode 16
\vspace{.2cm}
```{.c .verysmall}
```c
struct minix_inode {
u16 i_mode = 0x81C9; // 0x8 = regular file
// 0x1C9 = 711 in octal
......@@ -415,14 +407,11 @@ struct minix_inode {
## 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.
......@@ -443,44 +432,51 @@ Contenu du bloc indirect référencé par l'inode 11\
## Important : inodes
\small
<div style="font-size: 0.8em">
- 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
- Le premier inode de la table (à l'indice 0) est l'inode 1, il n'y a donc pas d'inode 0 !
- **Attention** : le bit 0 du bitmap indique l'état de l'inode 0 !
- 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}
</div>
<br>
<fieldset>
<legend>En conséquence :</legend>
- 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
</fieldset>
</div>
--
## Important : blocs de données
\small
<div style="font-size: 0.8em">
- 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**\ !
- **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}
</div>
<br>
<fieldset>
<legend>En conséquence :</legend>
- 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
<small> *firstdatazone* et *nzones* sont les champs du même nom dans le superbloc</small>
</fieldset>
<!--
-`firstdatazone` est le champs du même nom dans le superbloc (= nombre de blocs utilisés par\ : superbloc + bitmaps + table d'inodes)
......@@ -496,12 +492,10 @@ En conséquence[^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
......@@ -512,14 +506,12 @@ En conséquence[^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`
**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`
--
......@@ -528,7 +520,8 @@ Exemple de valeurs 8 bits, 16 bits et 32 bits, en représentation hexadécimale,
- **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}
<br></br>
- **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`
......@@ -537,7 +530,7 @@ Exemple de valeurs 8 bits, 16 bits et 32 bits, en représentation hexadécimale,
## Danger avec la sérialisation/déserialisation
```{.c .tiny}
```c
struct st1 { struct __attribute__ ((__packed__)) st2 {
uint8_t tab[7]; uint8_t tab[7];
uint16_t n; uint16_t n;
......@@ -552,22 +545,6 @@ int main() {
}
```
::: 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
- Affichage ? `20 15` <!-- .element class="fragment" -->
- Pourquoi ? <text>Le compilateur ajoute des bytes de padding pour optimiser l'alignement des structures.</text> <!-- .element class="fragment" -->
- Conséquence : <text>**toujours** utiliser l'attribut `__packed__` sur les structures sérialisées !</text> <!-- .element class="fragment" -->
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment