[Kos-dev] [FAT] Mes remarques sur le travail de Thomas

Christophe kos-dev@enix.org
Mon, 25 Feb 2002 14:58:24 +0100


----- Original Message -----
From: Hervé Poussineau <herve.poussineau@cgey.com>
To: <kos-dev@enix.org>
Sent: Monday, February 25, 2002 2:31 PM
Subject: [Kos-dev] [FAT] Mes remarques sur le travail de Thomas


>     Salut Thomas (et les autres, bien entendu)
>
> J'ai relu le remarquable travail que tu as fait sur la FAT, et j'ai
quelques
> remarques :
>
> * [fat] Name/extension is too long : impossible for FAT16
> (_fat_analyze_name)
> Pas du tout : FAT12, 16, 32 sont le nombre de bits utilisés pour coder le
> numéro d'un cluster ; les noms longs peuvent se trouver sur ces trois
types
> de filesystem, grâce à la VFAT. (pour info, les noms longs sont stockés
dans
> des entrées de répertoire dont l'attribut est 0xf, que tu sautes déjà).
Les
> limites des noms longs sont name < 255 caractères, ext < 255 caractères et
> name+'.'+ext < 255 caracteres.
>

Cette remarque est tout-à-fait pertinente, la VFAT est totalement
indépendant du fait que la FAT soit 12-bit, 16-bit ou 28-bit (eh oui ! ce
n'est pas un vrai 32-bit !). La VFAT détermine une entrée de répertoire
spéciale souvent appelé "slot" et qui se reconnait effectivement à
l'attribut 0xf. Quant aux limites des noms, je n'ai pas trouvé à ce jour des
spécifications claires là-dessus. Il s'avère que techniquement un long nom
peut être enregistré sur 32 slots au maximum (12 caractères unicode je crois
par slot), ce qui fait théoriquement 384 caractères unicode maximum.
Cependant, je crois que Windows et Linux s'arrête à 256 caractères, donc je
me rangerais du même avis qu'Hervé.

Pour la petite histoire des 28-bit au lieu des 32-bit pour la FAT32, je me
demande si ce n'est pas lié à la valeur maximum pour le LBA des contrôleurs
ATA/ATAPI (en effet, rien n'empêche qu'un cluster d'une FAT32 ne fasse que
512 octets, soit un secteur). D'autre part, il y a un flag dans le secteur
fsinfo de la FAT32 qui détermine quelle est la FAT active quand le flag "FAT
mirroring" est désactivé - ce qui veut dire que la FAT 0 n'est pas forcément
celle qui va contenir les modifications quand le "mirroring" n'est pas
activé. Bon je reconnais que je n'ai pas rencontré un seul disque dur qui
ait désactivé le "mirroring" mais il faudra veiller à le gérer si ce n'est
pas déjà fait (pas encore vu le source mais je ne tarderais pas). Par
ailleurs, le numéro actif de FAT est compris entre 0 et 15 et présente le
même nombre de bits (4) que celles "non-utilisées" dans une entrée de FAT32
: il y aurait-t-il un lien caché ? je me pose cette question car j'ai le
vague souvenir d'avoir lu quelquechose là-dessus par Microsoft (qui comme
d'habitude en parle sans donner les détails que l'on voudrait).

> * parcours du répertoire (fat_open_file)
> Ta boucle est for(i = 0; direntry[i].filename[0] != 0; i++) { ... }
> Tu auras des erreurs si le répertoire tient sur plus d'un cluster et que
ce
> n'est pas le répertoire racine. Je te propose plutôt le code suivant :
>   cluster = adresse du 1er cluster du répertoire (attention; pas calculé
de
> la même manière si répertoire racine ou sous-répertoire)
>   répéter
>     direntry[] = hd_read(cluster, sectors_per_cluster)
>     for(i = 0; direntry[i].filename[0] != 0 && i < 32*sectors_per_cluster;
> i++)
>       {
>         si fichier trouvé { ... ; terminé = TRUE; break; }
>         if(direntry[i].filename[0] == 0) { terminé = TRUE; break; }

Vérifie qu'il ne soit pas nécessaire que tu sortes qu'après avoir rencontrer
32 fois filename[0] == 0 d'affilé, i.e, quand tu lis plus d'un secteur !
j'ai vu ça dans le source d'un gars mais j'ignore si c'est uniquement lié à
sa manière de supprimer les entrées de nom long, ou si effectivement la
suppression d'un slot met le filename[0] à 0. Je vérifierais ça.

>       }
>     if (lecture_du_repertoire_racine == TRUE)
>       cluster++;
>     else
>       cluster = next_cluster(cluster)
>   jusqu'à (terminé == TRUE || cluster >= 0xfff8)
>

> * int _fat_init(void)
> Tu fais la détection grâce à :
>   if(countclusters < 4085)
>     fat_data->type = FAT12;
>   else if(countclusters < 65525)
>     fat_data->type = FAT16;
>   else
>     fat_data->type = FAT32;
> Ces valeurs sont des valeurs maximales, et ne sont pas toujours respectées

Exact.