Je constate des écritures différées dans le FAT sur un lecteur flash USB formaté FAT (FAT12) de petite capacité, même si la politique du lecteur est définie sur «Suppression rapide». (Je crois que cela signifie que le SurpriseRemovalOK
drapeau est réglé). J'ai capturé les commandes SCSI envoyées au lecteur via USB: les écritures de troncature de fichier se produisent immédiatement, le fichier entier (2 secteurs de 512 octets de long) est écrit immédiatement après cela, mais il y a ensuite un délai de 20 à 90 secondes avant le FAT est mis à jour pour refléter l'écriture du fichier.
La taille du disque est importante. J'ai testé avec et je vois des problèmes sur les systèmes de fichiers FAT de taille 15 Mo et moins. Sur 16 Mo et plus, les écritures ne sont pas retardées. 16 Mo est le point d'arrêt que je vois entre l'utilisation de FAT12 et FAT16 lorsque je formate un lecteur sous Windows. (Remarque ajoutée plus tard: mais le point d'arrêt FAT12 / FAT16 dépend du nombre de clusters, et non de la taille absolue du système de fichiers).
Sur 16 Mo et plus, Windows envoie des Prevent/Allow Medium Removal
commandes SCSI avant les écritures, demandant que le périphérique ne soit pas supprimé. La clé USB renvoie en fait un échec à ces demandes (car elle ne peut garantir aucune suppression), mais Windows essaie quand même. Les 15 Mo et les traces plus petites ne montrent aucunePrevent/Allow Medium Removal
commande.
(J'ai découvert ce problème en utilisant une carte de microcontrôleur qui prend en charge un petit système de fichiers FAT contenant du code Python. Lorsque le microcontrôleur détecte une écriture dans le système de fichiers, il attend un peu que l'écriture se termine, puis redémarre automatiquement et exécute le code Python nouvellement écrit Mais le microcontrôleur voyait du code corrompu ou un système de fichiers corrompu en raison de l'écriture retardée.)
Pourquoi l'écriture dans le FAT est-elle retardée si longtemps, malgré le "retrait rapide" défini? Je peux forcer les écritures en faisant un "Eject" sur le lecteur mais cela va à l'encontre de la promesse de "Quick Removal". Si je tirais le disque tôt, il y aurait une table FAT incorrecte. Cela dément la déclaration de la capture d'écran ci-dessous à propos de ne pas avoir à utiliser "Retirer le matériel en toute sécurité". Est-ce un bug ou est-ce que je manque quelque chose? Existe-t-il un moyen de forcer toutes les écritures à se produire immédiatement sans "éjection" manuelle?
Voici un extrait élagué d'une trace Wireshark / USBPcap montrant le problème. Je tronque un fichier existant, puis j'en écris une nouvelle copie. J'ai ajouté des commentaires avec ###
. La plupart des écritures sur la clé USB ont lieu environ 5 secondes après la trace, mais l'écriture finale en FAT ne dure que 26 secondes.
No. Time Source Destination Protocol Length Info
### write directory entry to truncate file
13 5.225586 host 1.2.2 USBMS 58 SCSI: Write(10) LUN: 0x00 (LBA: 0x00000041, Len: 8)
14 5.225838 host 1.2.2 USB 4123 URB_BULK out
### write FAT entries to truncate file
16 5.230488 host 1.2.2 USBMS 58 SCSI: Write(10) LUN: 0x00 (LBA: 0x0000003b, Len: 1)
17 5.230707 host 1.2.2 USB 539 URB_BULK out
19 5.235110 host 1.2.2 USBMS 58 SCSI: Write(10) LUN: 0x00 (LBA: 0x0000003e, Len: 1)
20 5.235329 host 1.2.2 USB 539 URB_BULK out
### write directory entry for
22 5.252672 host 1.2.2 USBMS 58 SCSI: Write(10) LUN: 0x00 (LBA: 0x00000041, Len: 8)
23 5.252825 host 1.2.2 USB 4123 URB_BULK out
### write out file data (2 sectors of 512 bytes)
25 5.257416 host 1.2.2 USBMS 58 SCSI: Write(10) LUN: 0x00 (LBA: 0x000000c1, Len: 2)
26 5.257572 host 1.2.2 USB 1051 URB_BULK out
### 20 second delay
### finally, write FAT entries to indicate used sectors
79 26.559964 host 1.2.2 USBMS 58 SCSI: Write(10) LUN: 0x00 (LBA: 0x0000003b, Len: 1)
80 26.560191 host 1.2.2 USB 539 URB_BULK out
82 26.560834 host 1.2.2 USBMS 58 SCSI: Write(10) LUN: 0x00 (LBA: 0x0000003e, Len: 1)
83 26.560936 host 1.2.2 USB 539 URB_BULK out
J'ai généré des traces comme celle-ci à l'aide d'un lecteur flash standard et également avec une carte microcontrôleur qui émule un minuscule lecteur USB MSC, à la fois sur Windows 7 et Windows 10.
Juste pour être clair, il s'agit d'un lecteur au format FAT12, juste appelé "FAT" dans l'outil de formatage Windows.
la source
main.py
des fichiers similaires lorsqu'elle détecte que le fichier a été écrit. Cela retarde un peu la fin de l'écriture, mais pas des dizaines de secondes. Nous pouvons désactiver ce redémarrage automatique, mais il est toujours nécessaire d '"éjecter" le lecteur pour vous assurer que l'écriture se termine en temps opportun. Obliger l'utilisateur à effectuer une éjection est une nuisance; nous aimerions éviter cela.Réponses:
J'ai peut-être trouvé le code de pilote Windows réel à l'origine du problème.
Il se trouve que MS inclut le pilote du système de fichiers FAT dans un package d'exemple de code de pilote. Il y a plusieurs endroits dans ce pilote où, si le système de fichiers est FAT12, le pilote ne prendra pas la peine de faire quelque chose comme définir le bit sale (peut-être il n'y en a pas pour FAT12) ou vider les données FAT.
https://github.com/Microsoft/Windows-driver-samples/blob/master/filesys/fastfat/verfysup.c#L774 https://github.com/Microsoft/Windows-driver-samples/blob/master/filesys /fastfat/cachesup.c#L1212 et peut-être le plus critique: https://github.com/Microsoft/Windows-driver-samples/blob/master/filesys/fastfat/cleanup.c#L1101
Dans le dernier lien, dans
cleanup.c
, le FAT n'est pas vidé si le système de fichiers est FAT12. Je pense que cela peut être à l'origine du comportement que je vois:Signalé à Microsoft dans Windows Feedback Hub à https://aka.ms/btvdog (URL spéciale qui s'ouvre dans Feedback Hub).
la source