Le schéma ci-dessous représente une partition formatée en F.A.T
----------------------------------------------
| BA | FAT | Copie FAT | Tableau de clusters |
----------------------------------------------
- BA = Boot Area\footnote{BA == BR == Boot Record}
- FAT = Index
Le tableau de clusters est constitué de clusters de même taille. Un cluster ne peut contenir qu'un seul fichier.
1 cluster == n * secteur défini\footnote{cluster == bloc}
La FAT est l'index du tableau de clusters, il est chargé en RAM au démarrage pour des raisons de performance. La FAT contient autant d'entrée que de clusters présent dans le tableau de clusters. Cependant une entrée n'occupe pas nécessairement un cluster. La FAT contient l'adresse des clusters. Elle fait le lien entre les différents clusters d'un fichier.
Une entrée dans la fat peut avoir plusieurs valeurs :
- 0 si le cluster est libre \footnote{ne veut pas dire que le cluster est vide, seulement qu'il est libre}
- Une valeur positive pour désigner l'adresse du cluster suivant.
- -1 si c'est le dernier cluster.
- -2 si le cluster est défectueux. Comment savoir si un cluster est défectueux ? On écrit dedans, on lit ce qu'on a écrit, si les valeurs sont différentes, alors le cluster est défectueux.
Le répertoire racine se trouve trouve toujours au cluster 0 dans une partition formatée en FAT16. En FAT32, le cluster est donné par le MBR.
Les \textbf{répertoires en FAT sont des fichiers} particuliers contenant les métadonnées des fichiers présent dans le répertoire. Pour chaque fichier, le répertoire possède un descripteur de 32 bytes.
Les champs d'un descripteur :
- Nom : permet de connaître le nom du fichier.
- Cluster : l'adresse du premier cluster du fichier.
- Dates : dates de modification, création, dernier accès.
- Extension : l'extension du fichier
- Taille : la taille du fichier.\footnote{32Bits !, raison de la taille max d'un fichier de $2^{32}$}
Un répertoire a donc toujours au moins deux descripteurs : le descripteur du répertoire courant et le parent (sauf la racine qui n'a pas de parent).
Avantages de la FAT :
- Très simple à intégrer.
Inconvénients de la FAT :
- Lourd en mémoire si la partition est trop grande.\footnote{#bloc * taille entrée FAT}
- Si le nom est trop long, il peut être étalé sur plusieurs entrées.
- Pas de droits d'accès.
- Fragmentation externe, les clusters ne sont pas toujours contigus lorsqu'on écrit et efface beaucoup.
- Fragmentation interne, un cluster ne peut contenir qu'un seul fichier, si celui-ci n'est pas remplit, on perd de la place.
Voir les questions secondaires FAT.
Voir question ext/ext2 (dernière) pour les différences
EXT :
En EXT, un mini-disque (une partition) est composée de quatres zones :
- Boot Area : Contient les informations sur le démarrage
- Super-bloc : Contient les informations sur le mini-disque
- Tableau d'inodes : contient les inodes (métadonnées des fichiers)
- Tableau de blocs : contient les blocs (les données)
-------------------------------------------------
| BA | SB | Tableau d'inodes | Tableau de blocs |
-------------------------------------------------
La liste des blocs est variable alors que le tableau d'inde est fixe.
Le tableau d'inode contient un inode par fichier. Pour accéder à un fichier, il faut connaître l'inode, cet inode comprend :
- Nom du propriétaire 2bytes
- Groupe 2 bytes
- Dates 4 bytes
- Taille 4 bytes
- Type (fichier / dossier) 4 bytes
- Droits d'accès
- Liste de tous les blocs du fichiers
- 10 directs
- 1 avec redirection simple (TAILLE BLOC / 4 BYTES = nombre d'adresses)
- 1 avec redirection double (simple * simple = nombre d'adresses)
- 1 avec redirection triple (simple * simple * simples = nombre d'adresses)
Le chaînage est donc fait dans l'inode lui même. La liste de tous les blocs contient 10 pointeurs (12 en ext2) de blocs direct, et 3 pointeurs avec indirection.
-
Le 11ème pointeur contient un seul niveau d'indirection, il pointe vers un tableau de blocs qui pointe vers les blocs de données.
-
Le 12ème pointeur contient deux niveaux d'indirection, il pointe vers un tableau de blocs qui pointent eux même sur un tableau de blocs qui pointent sur les blocs de données.
-
Le 13ème pointeur contient trois niveaux d'indirection. il pointe vers un tableau de blocs qui pointent eux même sur un tableau de blocs qui pointent eux même sur un tableau de blocs qui pointent vres les blocs de données.
Comme en FAT, un répertoire est un fichier dont les données forment la liste des fichiers qu'il contient. Chaque fichier est représenté par deux champs, son nom et son numéro d'inode. Le répertoire racine en EXT a toujours l'inode numéro 2. Les blocs défectueux ont l'inode 1.
Le superbloc est spécifique à EXT, il contient des informations sur les tableaux d'inodes et de blocs. Il permet de connaître leur position, le nombre d'inodes, le nombre de blocs, la taille d'un bloc.
En EXT : Le superbloc gère également les blocs libre. Il contient un bloc dont les données sont des adresses de blocs libres. La dernière adresse du bloc pointe vers un autre bloc contenant aussi des adresses de blocs libres et ainsi de suite. L'avantage de ce système est qu'il ne prend aucune place sur le disque.
Superbloc 0 1 2 3 4 5
----- -------------------------
|1|2| | | | | |5|6| |
|3|4| | | | | |7|8| |
----- -------------------------
En EXT2 : Le superbloc ne gère plus la gestion des blocs libres, ce sont les blocs bitmap et inodes bitmaps pour la gestion des inodes libres.
Dans l'exemple ci-dessus, les blocs 1, 2, 3, et 4 sont libres dans le superbloc. La dernière adresse est 4. On va donc voir dans le bloc 4 pour les prochains blocs libres, celui-ci nous dit que les blocs 5, 6, 7 et 8 sont libres et qu'il faut aller dans le bloc 8 pour connaître la suite des blocs libres.
Voir questions liens soft/hard pour les liens.
Détaillez comment l'OS permet de découper un disque en plusieurs partitions (primaire, logique, étendue). Quelles sont les limites de cette technique ? Comment évolue-t-elle ? Quels sont les outils utilisés pour gérer ces partition (mkfs, fdisk, mount, unmount, df, /dev, ...)
A l'époque, on avait 4 partitions maximum. Le disque a un MBR et chaque partition à un BR.
MBR = programme d'amorce + table des partitions.
Table des partitions :
- 4 entrées (16 bytes)
- status 1 byte
- CHS 3 bytes (obsolete)
- ..
- type 1 byte
- numéro preimer secteur partition, 4 bytes
- numéro dernier secteur partition, 4 bytes
Comment avoir plus de partions ?
Partition primaire > partition étendue > partition logique
--------------------------------------------------------------------------------
|PRIMAIRE |PRIMAIRE |PRIMAIRE |PRIMAIRE |
--------------------------------------------------------------------------------
| | | | |
| | | | |
| | | | |
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
|PRIMAIRE |ETENDUE |PRIMAIRE |PRIMAIRE |
--------------------------------------------------------------------------------
| | | | |
| | | | |
| | | | |
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
|PRIMAIRE |ETENDUE |PRIMAIRE |PRIMAIRE |
--------------------------------------------------------------------------------
| |BR |EBR|LO |EBR|LO | | |
| | | |GIQ| |GIQ| | |
| | | |UE | |UE | | |
--------------------------------------------------------------------------------
Chaque partition logique a un EBR == programme d'amorce + table de partitions avec des entrées de type "numéro de secteur + taille + numéro section.
mount PARTITION REPERTOIRE
pour monter un minidisk
mount /dev/sda7 /home/dir_créé_pour_sda7
umount REPERTOIRE
pour démonter un minidisk
umount /home/dir_créé_pour_sda7
df
connaitre les minidisk montés et leurs informations.
dmesg
afficher des logs contenu dans le buffer du ring kernel
\footnote{voir
la notion de ring}
/etc/fstab
est un fichier contenant des informations sur le F.S. lu uniquement
par les programmes.
fdisk
pour manipuler une table de partition d'un disque.
mkfs -t ext /dev/sdb1
et mkfs -t vfat /dev/sdb2
donc un type de F.S.
GPT
= Global Partition Table
pour des partitions supérieure à 2.2Tio
(FAT) Détaillez comment l'OS retrouve un fichier, ajoute des données à ce fichier, efface ce fichier
Exemple pour retrouver un fichier : int h = open("/home/user/f1", O_RDONLY);
- En FAT16 : Le cluster 0 contient la racine. Dans la liste des descripteurs présent dans le répertoire racine, l'OS cherche un descripteur avec le nom "user". Si il le trouve, il cherche le descripteur avec le nom "f1" dans user. Dans le descripteur de f1, on a le premier cluster du fichier ainsi que sa taille. Les clusters suivant sont chainés et sont retrouvés grâce à la FAT.
- En FAT32 : Même principe qu'en FAT16, sauf que le répertoire racine est retrouvé grâce au MBR.
Supprimer un fichier : On met 0 dans la FAT aux clusters correspondant au fichier.
Ecrire dans un fichier : Il est très simple d'écrire dans un fichier, il suffit de changer le chainage en fat si on utilise de nouveaux clusters.
Lors d'un arrêt brutal du système, la FAT peut comporter des erreurs par rapport au contenu des clusters. Le système analyse le disque :
- Si la suite d'un fichier est un cluster vide, on remplace l'adresse par -1.
- Si on trouve un cluster qui contient des données mais ne semble appartenir à aucun fichier, et qu'il n'est pas libre.
(EXT2) Détaillez comment l'OS retrouve un fichier, ajoute des données à ce fichier, efface ce fichier.
handle = open("/usr/home/d", O_RDONLY);
- / (root) == inode 2 => Numero de bloc 28
- bloc 28 => contient l'entrée "usr, inode 35"
- usr/ == inode 35 => Numero de bloc 64
- bloc 64 => contient l'entrée "home, inode 11"
- home/ == inode 11 => Numero de bloc 77
- bloc 77 => contient l'entrée "d, inode 45"
- d == inode 45, l'ensemble des blocs appartiennent au fichier "d".
Intégrité des liens hard : On parcourt tout le F.S, on regarde le nombre de liens dans l'inode d'un fichier et on compare avec le nombre de fichiers ayant cet inode. Si le compteur d'inode est incohérent, on le corrige.
Fichier fantôme : fichier référencé dans un inode mais aucun fichier avec cet inode n'est référencé dans un répertoire.
La réponse est présente dans la question principale sur EXT. + Dernière question sur ext/ext2
La réponse est présente dans la question principale sur EXT. + Dernière question sur ext/ext2
(EXT2) Détaillez les appels système qui permettent d'utiliser le système de fichier (open, read, write, close, dir, dup, lseek, stat, ...) et comment l'OS implémente ces appels système (handle, TDFO, ...)
int creat(const char * pathname, mode_t mode);
int open(const char * pathname, int flags);
int open(const char * pathname, int flags, mode_t mode);
int close(int fd);
open
retourne un descripteur de fichier, c’est-à-dire une entrée dans la table
des handle du process pointant vers la table des fichiers ouverts (TDFO
).
Un descripteur de fichier reste ouvert par défaut après une fonction exec
car
elle n’écrase pas la table des handle du process.
creat
retourne également un descripteur de fichier. open
peut s’occuper de la création si le flag O_CREAT
est spécifié.
close
ferme un descripteur de fichier et supprime son entrée de la table des handle.
Si le descripteur spécifié en paramètre est le dernier descripteur correspondant
à un fichier ouvert dans la TDFO
, alors les ressources sont libérées dans cette
dernière. close
retourne 0
si il réussit, -1
sinon.
open
crée une nouvelle entrée dans la table des descripteurs des fichiers ouverts
(TDFO
) s’il n'est pas déjà ouvert, sinon il partage cette entrée. Cette entrée
comprend l'offset et le statut du fichier.
Flags de open :
O_RDONLY
: lecture seulementO_WRONLY
: écriture seulementO_CREAT
: créationO_RDWR
: lecture et écritureO_APPEND
: offset positionné à la fin du fichier comme si on utilisait un lseekO_TRUNC
: Le fichier est "tronqué" (le contenu est supprimé)
Il est évident que pour O_APPEND
et O_TRUNC
, il faut un flag en écriture.
L’effet de O_RDONLY
| O_TRUNC
est indéfini et varie selon les implémentations,
mais a de grande chance d'être tronqué.
On peut utiliser plusieurs flags en les séparant avec le séparateur de flags
|
, le ou binaire
.
Dans le cas d'une création, il faut spécifier un mode. Le mode est ignoré si
O_CREAT
n'est pas présent. Le mode correspond aux droits du fichier une fois
créé.
#include <unistd.h>
ssize_t read(int fd, void * buffer, size_t buffer_size);
fd
correspond au descripteur de fichier retourné paropen/creat
, dans la table des handles.buffer
correspond à la zone mémoire où iront les données lues.buffer_size
correspond au nombre d'octet qui doivent être lus à partir de l'offset du fichier spécifié dans laTDFO
. Si l’offset vaut \texttt{E.O.F.}, rien n'est lu etread()
retourne0
.read
retourne le nombre de bytes lus ou0
si la fin du fichier est atteinte. L’offset du fichier est avancé par ce nombre.
#include <unistd.h>
ssize_t write(int fd, const void * buffer, size_t buffer_size);
fd
correspond au descripteur retourné paropen/creat
.buffer
correspond à la zone mémoire contenant les données à écrire dans le fichier.buffer_size
correspond au nombre d'octet à écrire.write
retourne le nombre de bytes écrit dans le fichier. Ce nombre peut être plus petit quebuffer_size
si la place est insuffisante sur le disque dur.write
retourne-1
si erreur.write
écrit à l'offset du fichier. Cet offset est incrémenté par le nombre de bytes écrit.
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
lseek
a pour but de repositionner l'offset du fichier ouvert associé au
descripteur de fichier fd
spécifié en paramètre.
offset
correspond au décalage par rapport à l'offset courant.whence
correspond à la position de départ du décalage.SEEK_SET
: correspond au début du fichier.SEEK_CUR
: correspond à la position actuelle de l'offset.SEEK_END
: corresond à la fin du fichier.
- lseek retourne la nouvelle position de l'offset par rapport au début du
fichier. Si il y a erreur,
-1
est retourné.
int position_actuelle = lseek(fd, 0, SEEK_CUR); // Connaitre l'offset de la TDFO
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char * path, struct stat * buf);
int fstat(int fd, struct stat * buf);
int lstat(const char * path, struct stat * buf);
stat
permet d'obtenir des informations contenues dans l'inode d'un fichier.
L'utilisateur doit avoir le droit d'accéder au dossier parent de ce fichier mais
ne doit pas nécessairement avoir de droits pour ce fichier.
Quelques champs utiles de la structure stat (man 2 stat
pour voir la structure
complète).
stat / lstat
:path
correspond au nom du fichier.buf
correspond à l'adresse d'une zone où seront stockées les informations correspondantes au fichier (adresse d'une structure stat, voir ci-dessous).
fstat
fd
correspond au descripteur de fichier.buf
correspond à l'adresse d'une zone où seront stockées les informations correspondantes au fichier (adresse d'une structure stat, voir ci-dessous).
lstat
est identique à stat
, sauf que si le fichier est un lien soft, alors les
informations obtenues concernent ce lien. Pour stat
, si le fichier est un lien
soft, alors les informations obtenues concernent le fichier sur lequel ce lien
pointe.
struct stat
{
ino_t st_ino; // numéro de l'inode
mode_t st_mode; // les permissions
nlink_t st_nlink; // Nombre de liens hard
uid_t st_uid; // user ID du propriétaire
gid_t st_gid; // group ID du propriétaire
off_t st_size; // la taille en bytes
blksize_t st_blksize; // La taille des blocs
blkcnt_t st_blocks; // Nombre de blocs de 512 bytes alloués
time_t st_atime; // Date/heure du dernier accès
time_t st_mtime; // Date/heure de la dernière modification
};
#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);
dup
et dup2
créent une copie de l'entrée du descripteur oldfd
.
-
dup
crée une copie de oldfd et retourne le plus petit descripteur de fichier non utilisé comme nouveau descripteur. -
dup2
fait denewfd
la copie deoldfd
et fermenewfd
si celui-ci est ouvert.
Exemple : rediriger la sortie standard vers un fichier :
close(1);
int nouveau_h = dup(h_fichier);
close(h_fichier);
dup2(h_fichier, 1);
close(h_fichier);
Ces deux codes ci-dessus font exactement la même chose.
-
Dans le cas du
dup
: On ferme1
qui correspond à la sortie standard, ce qui le rend non utilisé. On fait ensuite undup(h_fichier)
qui va copier le descripteurh_fichier
dans l'entrée la plus petite dans la table des handle, ici1
étant donné qu'on vient de le fermer. L'entrée1
eth_fichier
pointe donc vers le fichier ouvert deh_fichier
dans laTDFO
. On ferme ensuiteh_fichier
car on en a plus besoin. L'entrée de la table des handle1
pointe donc vers le fichier ouvert qui correspondait àh_fichier
dans laTDFO
. Quand on va écrire sur la sortie standard (1
), on va donc écrire sur le fichier. -
Dans le cas de
dup2
, c'est exactement la même chose, sauf qu'il ferme1
lui-même.
#include <sys/types.h>
#include <dirent.h>
DIR * opendir(const char * name);
Ouvre un flux sur le répertoire correspondant au nom passé en paramètre.
#include <dirent.h>
struct direct * readdir(DIR * dir);
- Retourne un pointeur vers une structure dirent qui représente la prochaine
entrée dans le flux pointé par
dir
. Retourne NULL si la fin du répertoire est atteinte ou si une erreur survient. - La structure dirent est détaillée ci-dessous :
struct dirent
{
ino_t d_ino; // Numéro d'inode
char d_name[256]; // Le nom du fichier
};
Seuls les deux fichiers ci-dessus font partie du standard. Les autres champs (visibles grâce à man 3 readdir) ne sont pas implémentés dans tous les systèmes.
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR * dir);
closedir
ferme le flux associé à dir
. Retourne -1 si une erreur survient, 0
sinon.
#include <unistd.h>
int pipe(int pipefd[2]);
pipe
créé un pipe (canal unidirectionnel qui est utilisé dans la communication
inter-process). Le tableau pipefd
est utilisé pour retourné deux descripteurs
de fichiers où :
- pipefd[0] correspond à la sortie du pipe, "la source" du flux qui peut être lu.
- pipefd[1] correspond à l'entrée du pipe, "l'entonnoir" du flux qui peut être rempli.
Exemple : ls | wc -c
int p[2];
pipe(p);
if(fork() == 0)
{
close(p[0]); // Ne lit pas dans le pipe
dup2(p[1], 1); // La sortie standard devient l'entrée du pipe
close(p[1]);
execlp("ls", "ls", NULL);
}
if(fork() == 0)
{
close(p[1]); // N'écrit pas dans le pipe
dup2(p[0], 0); // L'entrée standard devient la sortie du pipe
close(p[0]);
execlp("wc", "wc", "-c", NULL);
}
close(p[0]);
close(p[1]);
Table des handles : propre à tout processus, répertorie tous les fichiers ouverts par le processus et les lie à une entrée dans la \texttt{T.D.F.O.}. Les trois premières entrée sont déjà ouverte par défaut
int handle = open("file", FLAGS);
---------------------
|0 | STDIN |
|1 | STDOUT |
|2 | STDERR |
|3 | HANDLE |
--------------------
Table des descripteurs de fichiers ouvert : chaque entrée (indice) possède un
compteur de "fichiers ouvert", le offset\footnote{position} et un numéro inode
du fichier. Lors d'un close(handle);
, si le compteur tombe à zero, les
ressources du fichier sont liberées.
----------------------------
i--|CPT |OFFSET |INODE |
----------------------------
0--|1 | 18 | 32 |
1--|2 | 0 | 31 |
2--|3 | 3 | 14 |
3--|6 | 8 | 27 |
----------------------------
-
Les liens hards : on souhaite que plusieurs utilisateurs puissent accéder au même fichier mais sous plusieurs noms différents à des path différents (le nom peut être le même car le nom est renseigné dans le répertoire parent, non dans l'inode). Ces deux fichiers partagent le même inode, ce qui signifie que les deux fichiers ne sont en fait qu'un seul et unique fichier. Cependant ces deux fichiers doivent se trouver sur le même mini-disque, car il n’est pas possible de savoir de quel inode on parle sinon. Si un des deux fichiers est modifié, le 2e le sera également étant donné qu'il s'agit du même fichier. Dans l'inode du fichier, un compteur de lien hard est présent, ce compteur est décrémenté quand un des deux fichiers est supprimé et est incrémenté quand un nouveau lien hard est créé sur ce fichier. Les blocs du fichier de base sont libérés seulement quand le compteur passe à 0 (
ls -l
permet de voir le nombre de liens pour chaque fichier). -
Les liens softs : Le lien soft, contrairement au lien hard, est un autre fichier. Les données de ce fichier sont le chemin du fichier pointé par le lien. Dans l'inode de ce fichier, le type est un lien. Un lien soft peut référencer un fichier sur un autre mini-disque. Quand on efface le lien, on efface seulement le lien, pas le fichier. Si on efface le fichier de base, le lien soft existe toujours mais n’est plus valable.
Pour créer des liens sur GNU/Linux :
- Liens hard :
ln fichier nom_lien
- Liens soft :
ln -s fichier nom_lien
(EXT2) Détaillez la notion de fichier creux à l'aide d'un exemple (création, taille, occupation du disque)
Exemple : On écrit dans un fichier "1" à la position 1
int handle = open("file", O_WRONLY);
write(handle, "1", 1);
et "2" à la position 100000.
lseek(handle, 100000, SEEK_CUR);
write(handle, "2", 1);
Lors d'une lecture, le système retournera des 0 binaires, mais il ne stocke pas sur le disque. Les blocs qui contiennent des 0 \textbf{ont l'adresse 0 dans l'inode (aucun bloc réservé)}. Dans ce cas le fichier n'occuperait que 3 blocs sur le disque : celui qui contient le "1", celui qui contient le "2" et le bloc pointé par la 11ème adresse. Alors que normalement un tel fichier devrait occuper 100 blocs.
- Sa taille \textbf{est bien de 100000 * 4 = 400000 Kio}.
- Son disk usage \textbf{est de 3}.
PS : On se déplace dans un fichier avec un lseek(), expliqué dans une autre question.
(EXT-EXT2) Détaillez la structure d'une partition formatée en EXT et EXT2. Détaillez les avantages d'EXT2 et l'implémentation de ces avantages. Comment EXT2 a t-il évolué ensuite ?
\
Défauts de l'EXT :
- Le nom d'un fichier/dossier ne peut pas dépasser 14 caractères.
- Les inodes et les blocs ne se trouvent pas au même endroit ce qui demande beaucoup de déplacement au niveau des têtes de lecture.
- Le superbloc contient des informations vitales pour le système et il n'en existe aucune copie.
- Problèmes de fragmentation : les blocs d'un fichier sont alloués aléatoirement.
Améliorations apportées par EXT2 :
Structure d'un groupe :
-------------------------
| 1 | 2 | 3 | 4 | 5 | 6 |
-------------------------
-
On peut améliorer les performances (moins de déplacement pour la tête de lecture) en regroupant les blocs d'un fichier dans une même zone.
-
Le mini-disque est maintenant divisé en groupes (4 par exemple). Chaque groupe possède une structure similaire au mini-disque.
- 1 : Copie du super bloc du mini-disque. Contient :
- nombre de blocs et d'inodes
- nombre de blocs et d'inodes libres (pour ne pas devoir recompter)
- la taille d'un bloc
- le nombre de blocs et d'inodes par groupe
- D'autres champs comme le nombre de montage, la date de dernière vérification sont présents.
- 2 : description du groupe
- 3 : Blocs bitmap : liste de bits où chaque bit représente un bloc. Si ce bite vaut 1, le blot est utilisé, sinon il est libre.
- 4 : Inode bitmap : liste de bits où chaque bit représente un inode. Si ce bit vaut 1, l'inode est utilisé, sinon il est libre.
- 5 : Inodes : ils contiennent maintenant 12 adresses directes et 3 indirections.
- 6 : Blocs
- 1 : Copie du super bloc du mini-disque. Contient :
-
Pour un répertoire, on essaye de regrouper les inodes de ses fichiers dans un même groupe mais de mettre ce répertoire dans un autre groupe que son parent.
-
Lorsqu'on veut allouer un bloc à un fichire, on fait la démarche suivante :
- On recherche un bloc voisin au dernier bloc alloué. On essaye qu'ils se trouvent sur la même piste à environ 16 blocs d'écart.
- Sinon on réserve 8 blocs libres (overbooking = réserver plus que ce qu'il ne faut), ce qui correspond à un byte dans le bloc bitmap.
- Sinon on recherche un bloc isolé dans le même groupe.
- Sinon on réserve 8 blocs dans un autre groupe.
-
Les noms de fichiers et répertoires ne sont plus limité à 14 bytes, possibilités d'avoir des noms longs. Une entrée d'un répertoire est maintenant structurée de la manière suivante :
- Numéro d'inode sur 4 bytes
- Longueur de l'entrée sur 2 bytes
- Longueur du nom de fichier sur 2 bytes
- Nom de fichier sur x bytes où x est un multiple de 4.
-
Si on doit effacer une entrée, la taille de la précédente augmente pour occuper l'espace libre. Cet espace pourra être utilisé pour une nouvelle entrée.
-
Si on renomme un fichier et que ce nouveau nom dépasse l'espace réservé, on copie l'entrée à la fin du dossier, on renomme le fichier et on efface l'ancienne entrée comme décrit ci-dessus.
-
Les liens symboliques sont spécifiques à EXT2.
Dans un tableau à deux entrées :
- Parcourir la liste des inodes et notes les blocs occupés.
- Parcourir la liste des blocs libre et les noter
-------------------------------------------------------------------------------
BLOC | 0 | 1 | 2 | 3 | ...
-------------------------------------------------------------------------------
LIBRE| 0 | 0 | 1 | 1 | ...
-------------------------------------------------------------------------------
BUSY | 1 | 0 | 1 | 0 | ...
-------------------------------------------------------------------------------
(LIBRE, BUSY) matches {
case (1, 0) => "OK"
case (0, 1) => "OK"
case (0, 0) => "bloc perdu, devient (1, 0)"
case (1, 1) => "bloc dans le lost+found car ""occupé"" donc peut-être important."
}