3.4. Étude de la structuration d'un disque
On se propose d'étudier une structuration pour des
disques dont la capacité est comprise entre 100 Mo. et 2 Go., les
secteurs étant de 4096 octets.
Les machines pour lesquelles ils sont destinés
manipulent des octets, des entiers sur 16 bits ou des entiers sur 32
bits.
Les concepteurs du système de gestion de fichiers ont
décidé de diviser chaque unité de disque (amovible ou non)
de la façon suivante:
- le descripteur du disque, qui contient
tous les renseignements nécessaires à son identification, les
paramètres variables de la structure, et une table donnant accès
aux fichiers.
- la table d'allocation de
l'espace, représentant l'espace libre sur le
disque.
- la zone des fichiers, qui contient
les descripteurs de fichiers et l'espace de données de ces
fichiers.
Un fichier est constitué de deux
parties:
- le descripteur de fichier qui contient
toutes les informations nécessaires à sa localisation, et qui
seront détaillées
ci-dessous.
- l'ensemble des zones
physiques, qui contiennent les données du fichier. Pour un fichier,
toutes les zones physiques du fichier ont la même taille, et sont
constituées d'un nombre entier de secteurs contigus. Par contre les
différentes zones d'un même fichier ne sont pas
nécessairement
contiguës.
A. Étude des descripteurs de fichiers.
Les descripteurs de fichiers doivent repérer l'ensemble
des zones du fichier. Pour permettre à un fichier de contenir un nombre
quelconque de zones, tout en ayant des descripteurs de taille fixe, les
descripteurs sont décomposés en une partie principale
(obligatoire) et des parties extensions (optionnelles). Les parties extensions
éventuelles ont la même structure que les parties principales, les
informations inutilisées étant simplement mises à 0 dans ce
cas. Par la suite nous appellerons descripteur cette structure, qu'elle soit
utilisée comme partie principale ou comme extension. Les descripteurs de
fichiers sont regroupés dans des secteurs du disque. Ces secteurs sont
chaînés entre eux, pour permettre la recherche des fichiers. Un
descripteur de fichier a la structure suivante:
. le nom du fichier sur
16 octets,
. des informations diverses
sur 12 octets,
. la longueur du
fichier, c'est-à-dire le nombre total d'octets du fichier,
. le nombre total de
zones du fichier,
. la taille des zones
en nombre de secteurs,
. l'“adresse”
de l'extension suivante (numéro de secteur et position dans le
secteur),
. l'“adresse”
de la dernière extension du fichier,
. la table des
numéros de premiers secteurs des premières zones.
A.1- En considérant que tout entier sur disque a
la même représentation qu'en mémoire centrale,
c'est-à-dire 16 ou 32 bits, déterminer la taille en octets
nécessaire à la représentation de chacune des informations
suivantes:
. un numéro de
secteur,
. la longueur du fichier,
c'est-à-dire le nombre total d'octets du fichier,
. le nombre total de zones du
fichier,
. la taille des zones en
nombre de secteurs,
. l'“adresse”
d'une extension (numéro de secteur et position dans le
secteur).
A.2- Déterminer la taille d'un descripteur en
fonction du nombre d'entrées q de la table des premiers secteurs de zones
dans un descripteur. En déduire la valeur maximale du nombre r de
descripteurs dans les secteurs du disque qui les contiennent, en fonction de q,
et la perte qui résulte d'un choix donné de r et q
compatibles.
A.3- Étudier en particulier les cas où ce
nombre q prend les valeurs 31, 32 et 33. Calculer la perte d'espace dans chaque
cas. Commenter le choix de 32.
A.4- Expliquer l'intérêt des
différentes informations (autres que diverses) qui sont présentent
dans la partie principale d'un descripteur. On distinguera celles qui sont
nécessaires et celles qui sont redondantes, et on justifiera cette
redondance. Montrer que l'on peut déduire de ces informations le nombre
d'extensions du descripteur de fichier.
B. Étude des descripteurs de disque
Nous avons déjà dit que les descripteurs de
fichiers étaient regroupés dans des secteurs du disque,
chaînés entre eux. Pour minimiser le parcours de ces secteurs lors
de la recherche d'un fichier, on partitionne les descripteurs en p ensembles
disjoints par un calcul sur le nom du fichier, H(nom), qui délivre
un entier entre 1 et p. Le descripteur du disque contient une table qui, pour
chacune des valeurs entre 1 et p, indique le numéro du premier secteur
contenant les descripteurs des fichiers dont le calcul H(nom) donne cette
valeur (fonction de hachage). Le descripteur du disque, qui doit tenir dans
un seul secteur du disque, est donc défini comme suit:
. le nom du disque sur
32 octets,
. le nombre total de
secteurs du disque,
. le nombre de secteurs
occupés,
. le nombre de fichiers
existants sur le disque,
. le nombre de descripteurs
de fichiers par secteurs,
. le nombre
d'entrées de la table de hachage,
. la table de hachage,
donnant pour chaque valeur de hachage le numéro du premier secteur des
descripteurs de fichiers.
B.1- En considérant que tout entier sur disque a
la même représentation qu'en mémoire centrale,
c'est-à-dire 16 ou 32 bits, déterminer la taille en octets
nécessaire à la représentation de chacune des informations
suivantes:
. le nombre de fichiers
existants sur le disque,
. le nombre de descripteurs de
fichiers par secteurs,
. le nombre d'entrées
de la table de hachage,
B.2- Le descripteur du disque devant tenir dans un seul
secteur, combien peut-il y avoir au plus d'entrées dans la table de
hachage? À quel endroit convient-il de mettre ce secteur sur le
disque?
B.3- Expliquer l'intérêt des
différentes informations qui sont présentent dans le descripteur
du disque. On distinguera celles qui sont nécessaires et celles qui sont
redondantes, et on justifiera cette redondance.
B.4- Comment jugez-vous ce système? Quels
avantages ou inconvénients y voyez-vous?
B.5- Définir la procédure d'ouverture d'un
fichier, ainsi que la procédure de lecture d'un octet quelconque de ce
fichier défini par sa position relative au début du
fichier.
Solution de l’exercice
3.4
3.4.1. Question A
3.4.1.1. Question A.1
- numéro de secteur. Un disque peut
contenir jusqu'à
2*230 / 4*210 = 219
secteurs. Il faut donc au moins 19 bits pour représenter un numéro
de secteur, soit un entier sur 32 bits, ou 4
octets.
- longueur du fichier. Un fichier ne
peut dépasser la taille maximale d'un disque, donc
2 * 230 = 231 Il faut donc des entiers
sur 32 bits, soit 4 octets pour représenter le nombre d'octets utile d'un
fichier.
- nombre total de zones et taille des
zones. En l'absence de contrainte, une zone physique d'un fichier doit
être d'au moins 1 secteur, mais pouvoir atteindre presque le disque
complet (à l'exception des informations structurelles). Un fichier peut
donc avoir 219 zones de 1 secteur; il faut donc 32 bits ou 4 octets
pour représenter le nombre total de zones du fichier. De même, un
fichier peut avoir 1 zone de 219 secteurs; il faut donc 32 bits ou 4
octets pour représenter la taille des zones du fichier. Notons qu'il ne
serait pas très contraignant et sans doute assez logique de limiter
chacune de ces quantités à 216, permettant ainsi
d'utiliser des entiers sur 16 bits ou 2 octets, puisque ceci nous donne de toute
façon 232 secteurs, valeur nettement supérieure au
nombre maximal de secteurs d'un
disque.
- adresse d'une extension. L'adresse
d'une partie extension d'un descripteur doit permettre de désigner d'une
part le numéro de secteur disque où la partie extension est
placée (19 bits), et d'autre part, sa position dans ce secteur. Celle-ci
peut être définie simplement par le numéro de son premier
octet (12 bits), donnant ainsi un total de 31 bits. Cette position peut aussi
être le numéro d'ordre du descripteur dans le secteur, puisque tous
les descripteurs sont de même taille. Par exemple, s'il y a au plus 32
descripteurs par secteur, 5 bits suffiront alors pour ce numéro, et une
adresse de partie extension nécessitera 24 bits. Enfin, en suivant la
politique de représentation des entiers en 16 ou 32 bits, on constate
alors qu'il faut 32 bits ou 4 octets dans tous les
cas.
3.4.1.2. Question A.2
Pour déterminer le nombre de descripteurs de fichiers
par secteur, il faut déterminer la taille d'un descripteur. Nous
reprenons les données numériques de la question A.1, et les notons
devant les informations du descripteur de fichier:
16
|
le nom du fichier sur 16 octets,
|
12
|
des informations diverses sur 12 octets,
|
4
|
le nombre total d'octets du fichier,
|
4
|
le nombre total de zones du fichier,
|
4
|
la taille des zones en nombre de secteurs,
|
4
|
l'“adresse” de l'extension suivante (numéro
de secteur et position dans le secteur),
|
4
|
l'“adresse” de la dernière extension du
fichier,
|
4*q
|
la table des numéros de premiers secteurs des
premières zones.
|
Il s'ensuit que le descripteur occupe
48 + 4 * q octets, où q est le nombre
d'entrées de la table des premiers secteurs de blocs d'un descripteur.
Les secteurs contenant des descripteurs étant chaînés entre
eux, le lien de chaînage occupe 4 octets, laissant libres 4092 octets pour
r descripteurs, et il s'ensuit que
r ≤ 4092 / (48 + 4 * q).
Pour une valeur de r compatible avec q, la perte est
4092 - r * (48 + 4 * q).
3.4.1.3. Question A.3
Nous avons les valeurs suivantes:
q
|
r maximum
|
perte
|
31
|
23
|
136
|
32
|
23
|
44
|
33
|
22
|
132
|
Le choix de 32 est le plus optimal, puisqu'il correspond
à la plus petite perte. Cependant, même s'il induisait une perte
supérieure aux autres, il pourrait être conservé car il a
l'avantage de permettre de représenter, dans chaque descripteur, qu'il
soit partie principale ou extension, un nombre de zones qui est une puissance de
2.
3.4.1.4. Question A.4
Le nom du fichier est nécessaire pour distinguer
les fichiers entre eux, et permet à l'utilisateur de désigner ce
fichier par une chaîne de caractères. La longueur du fichier
N est la seule information de taille qui permette de savoir exactement quels
sont les octets de l'espace alloué au fichier qui en font partie. La
taille des zones T est nécessaire pour déterminer la taille
des zones à allouer au fur et à mesure des besoins au fichier;
elle permet également de déterminer à quelle zone
appartient le nième secteur du fichier. L'adresse de
l'extension suivante est nécessaire pour parcourir les extensions du
descripteur. La table des numéros de premiers secteurs permet de
savoir où commence chaque zone sur disque, et donc détermine
l'espace alloué au fichier.
Le nombre total de zones du fichier est une information
redondante, en ce sens qu'elle peut être reconstruite à partir des
autres. En effet, le nombre de secteurs S est égal à (N-1)%4096+1,
où % désigne la division entière. À partir de la
taille des zones T, on peut déduire le nombre de zones
B = (S-1)%T+1. Elle évite de refaire ce calcul en particulier
pour déterminer la taille de l'espace occupé par le fichier sur le
disque. Enfin l'adresse de la dernière extension du fichier est
également une information redondante, puisqu'elle peut être connue
en parcourant les extensions successives. Elle est utile car l'allocation d'une
nouvelle zone lors d'un allongement du fichier, entraîne la modification
de cette extension.
Par ailleurs (B-1)%32 nous donne le nombre d'extensions du
fichier.
3.4.2. Question B
3.4.2.1. Question B.1
- nombre de fichiers. Le nombre maximum de
fichiers que l'on peut avoir s'obtient en divisant la taille maximale du disque
par la taille minimale occupée par un fichier. Si les fichiers
contiennent au moins 1 octet (pas de fichiers vides), l'espace qu'ils occupent
est alors au moins de 1 secteur, donc il y en a alors au plus 219. Si
on admet que tous les fichiers peuvent être vides (hypothèse
d'école!), leur nombre est limité au nombre de descripteurs
pouvant exister, et la taille nécessaire à la
représentation du nombre de fichiers existants sur le disque est la
même que celle des adresses de descripteurs, calculée ci-dessus. La
politique de représentation des entiers conduit donc à prendre 32
bits ou 4 octets. Remarquons que ceci est tout théorique, et que sans
doute 16 bits ou 2 octets seraient amplement suffisants. Néanmoins,
étant donné que cette valeur ne se retrouve que dans le
descripteur du disque, la perte de 2 octets est vraiment
négligeable.
- nombre de descripteurs par
secteurs. Le nombre de descripteurs de fichiers par secteur, dépend
de la taille d'un descripteur. Comme un tel descripteur contient au moins 16
octets (le nom), il y en a donc au plus 256 par secteur. Un octet peut suffire.
Comme il s'agit d'un entier, nous devons prendre 16 bits ou 2 octets pour sa
représentation.
- nombre d'entrées
de la table de hachage. La table de hachage étant incluse dans le
descripteur du disque, lui-même devant tenir dans un seul secteur, le
nombre de ses entrées est donc au plus égal à la taille
d'un secteur divisé par la taille de l'une de ses entrées. Comme
nous avons fixé plus haut à 4 octets la représentation des
numéros de secteur du disque, il y a donc au plus 1024 entrées, ce
qui nécessite 16 bits ou 2
octets.
3.4.2.2. Question B.2
Nous reprenons les données numériques des
questions A.1 et B.1, et les notons devant les informations du descripteur du
disque:
32
|
le nom du disque sur 32 octets,
|
4
|
le nombre total de secteurs du disque,
|
4
|
le nombre de secteurs occupés,
|
4
|
le nombre de fichiers existants sur le disque,
|
2
|
le nombre de descripteurs de fichiers par secteurs,
|
2
|
le nombre d'entrées de la table de hachage,
|
4*p
|
la table des premiers secteurs de descripteurs de
fichiers.
|
Il s'ensuit que le descripteur occupe
48 + 4 * p octets. Comme il doit tenir dans un secteur, il
s'ensuit que p ≤ (4096 - 48) / 4 =
1012.
Le système doit être capable de trouver le
descripteur d'un disque quelconque, avant d'avoir aucune information sur sa
structure. Ce descripteur doit donc être dans un secteur fixe pour tous
les disques. Il est alors logique de le mettre dans le secteur 0,
c'est-à-dire, secteur 0 de la face 0 du cylindre 0.
3.4.2.3. Question B.3
Le nom du disque permet d'attacher un
“label” au volume ainsi structuré. Les utilisateurs pourront
utiliser cette chaîne de caractères pour demander au système
de contrôler qu'il s'agit du bon volume. Le nombre total de
secteurs permet de connaître la taille du disque lui-même. Cette
information est parfois redondante, si le matériel impose le nombre de
secteurs par piste, le nombre de faces et le nombre de cylindres, mais ce n'est
pas toujours le cas. Le nombre de descripteurs de fichiers par secteurs
est nécessaire si le SGF admet que ce nombre varie d'un volume à
l'autre. Cette paramétrisation a l'avantage de faciliter l'adaptation de
la structure aux besoins des utilisateurs plutôt que de l'imposer en tant
que constante interne au système. Le nombre d'entrées de la
table de hachage permet d'adapter cette valeur à la capacité
du disque et au nombre de fichiers que l'on prévoit d'y mettre.
Le nombre de secteurs occupés est une
information redondante, puisqu'il suffit de parcourir l'ensemble de tous les
descripteurs de fichiers pour la retrouver. Le nombre de fichiers
existants est également une information redondante, puisque ce nombre
peut être obtenu par parcours des descripteurs de fichiers. La
conservation de ces valeurs évite ce parcours lorsqu'on désire
savoir quel est le taux d'occupation du disque, le nombre de fichiers, la taille
moyenne des fichiers, etc...
3.4.2.4. Question B.4
La désignation des fichiers dans ce système est
assez pauvre, puisque tous les fichiers sont désignés par un nom
sur 16 octets, et qu'il y a un répertoire unique pour l'ensemble des
fichiers du disque: il n'y a pas de structure arborescente. Cet
inconvénient peut être particulièrement important si les
fichiers sont de petite taille, et le disque de grosse capacité (500000
fichiers de 4Ko. par exemple). La présence de la table de hachage peut
améliorer nettement l'efficacité de la recherche d'un fichier,
puisqu'elle implique un partitionnement de l'ensemble des noms de fichiers en
1000 groupes environ. Cependant, il n'en reste pas moins qu'un tel
répertoire plat est désagréable pour les utilisateurs dans
leur construction et manipulation des noms de fichiers.
Ce système permet de prendre en compte des fichiers de
taille quelconque. Si l'utilisateur fixe correctement la taille des zones de son
fichier, et que les allocations contiguës de cette taille sont possibles,
le comportement peut se rapprocher de celui des systèmes à nombre
fixe maximum de zones, puisque alors son descripteur de fichier peut n'avoir
qu'une partie principale, sans extension. Si par contre, l'utilisateur fixe une
taille de zones égale à 1 secteur, il a la garantie de pouvoir
créer un fichier de taille quelconque, dans la limite de l'espace
réellement disponible, au prix d'une certaine perte d'efficacité
due au nombre de ses extensions si son fichier est de taille importante. Notons
cependant que les fichiers dont la taille est inférieure ou égale
à 128 Ko n'ont jamais besoin d'une extension, s'il y a 32 entrées
dans la table des numéros de premiers secteurs d'un
descripteur.
Notons qu'un disque de 100 Mo offre ici 25000 secteurs, alors
qu'un disque de 2 Go en offre 500000. Dans ce dernier cas, l'allocation au
niveau du secteur peut être jugée lourde et inefficace. Une
méthode courante pour diminuer cette difficulté est de
considérer que l'unité minimum d'allocation est de plusieurs
secteurs. Le seul changement à apporter à la structure est de
mémoriser dans le descripteur du disque cette unité d'allocation
en nombre de secteurs. Lors de la création d'un fichier, la taille
effective des zones est alors forcée au multiple de cette unité
d'allocation immédiatement supérieure ou égale à
celle demandée par l'utilisateur, sans qu'il ait à se
préoccuper de la valeur de cette unité d'allocation.
3.4.2.5. Question B.5
Donnons tout d'abord les structures manipulées dans un
langage “à la Pascal”.
type t_descripteur: article { représentation d'un descripteur }
nom: chaîne [16];
info: chaîne [12];
longueur: entier;
nb_zone: entier;
taille_zone: entier;
ext_suivante, dernière_ext: entier;
def_zone: tableau [0 .. 31] de entier;
fin article;
type t_sect_descr: article { représentation d'un secteur de descripteurs }
descr: tableau [0 .. 22] de t_descripteur;
suivant: entier;
fin article;
Nous
supposons que la table de hachage du disque est déjà
présente en mémoire centrale. La procédure suivante
d'ouverture de fichier initialise le descripteur de fichier qui lui est
passé en paramètre avec la partie principale si elle a
été trouvée, ou avec un descripteur invalide
sinon.
var tab_hachage: tableau [1 .. p] de entier; { supposé déja en mémoire }
procédure ouvrir (nom: chaîne [16]; var descr: t_descripteur);
var sect_descr: t_sect_descr;
s, i: entier;
non_trouvé: booléen;
début non_trouvé := vrai;
s := tab_hachage [H (nom)];
tantque s ≠ 0 et non_trouvé faire
lire_disque (sect_descr, s);
i := 0;
tantque i < 23 et non_trouvé faire
si sect_descr.descr [i].nom = nom alors non_trouvé := faux
sinon i := i + 1 finsi;
fait;
s := sect_descr.suivant;
fait;
si non_trouvé alors descr := descripteur_invalide
sinon descr := sect_descr.descr [i]; finsi;
fin;
Cette
procédure pourrait être complétée par la lecture des
extensions du fichier. Comme le nombre de zones du fichier est
mémorisé dans la partie principale, il serait alors possible de
constituer un tableau unique avec tous les numéros de premier secteur de
toutes les zones du fichier. Cependant si le fichier fait l'objet d'allongement
(écriture au bout), ceci peut conduire à augmenter la taille de
cette table au cours de l'exécution du programme, à moins de la
surdimensionner initialement pour réduire l'éventualité de
cet allongement.
La procédure de lecture d'un octet situé
à une position donnée, peut se définir comme
suit:
procédure lire (descr: t_descripteur; position: entier; var c: octet);
var sect_descr: t_sect_descr;
sect_donnée: tableau [0 .. 4095] de octets;
num_ext, num_zone, num_sect, num_oct: entier;
s, i: entier;
début num_oct := position mod 4096; { position dans le secteur de données }
position := position % 4096; { numéro relatif de secteur du fichier }
num_sect := position mod descr.taille_zone;{numéro du secteur dans la zone}
position := position % descr.taille_zone;{numéro relatif de zone du fichier}
num_zone := position mod 32; { numéro de zone dans l'extension }
num_ext := position % 32;
si num_ext = 0 alors s := descr.def_zone [num_zone]
sinon { lecture de l'extension si ce n'est pas fait lors de l'ouverture }
s := descr.ext_suivante;
tantque num_ext ≠ 0 faire
i := s mod nb_descr_par_secteur;
s := s % nb_descr_par_secteur;
lire_disque (sect_descr, s);
s := sect_descr.descr [i].ext_suivante;
num_ext := num_ext - 1;
fait;
s := sect_descr.descr [i].def_zone [num_zone];
finsi;
lire_disque (sect_donnée, s);
c := sect_donnée [num_oct];
fin;