Windows verzögert das Schreiben der FAT-Tabelle auf einem kleinen USB-Laufwerk trotz „Schnelles Entfernen“.


10

Auf einem FAT (FAT12) -formatierten USB-Flash-Laufwerk mit geringer Kapazität werden verzögerte Schreibvorgänge in die FAT angezeigt, obwohl die Richtlinie für das Laufwerk auf "Schnellentfernung" festgelegt ist. (Ich glaube, das bedeutet, dass die SurpriseRemovalOKFlagge gesetzt ist). Ich habe die SCSI-Befehle erfasst, die über USB an das Laufwerk gesendet wurden: Die Schreibvorgänge für das Abschneiden von Dateien erfolgen sofort, die gesamte Datei (2 512-Byte-Sektoren lang) wird unmittelbar danach geschrieben, aber dann gibt es eine Verzögerung von 20 bis 90 Sekunden vor dem FAT wird aktualisiert, um das Schreiben der Datei widerzuspiegeln.

Die Größe des Laufwerks ist erheblich. Ich habe mit FAT-Dateisystemen mit einer Größe von 15 MB und kleiner getestet und sehe Probleme. Ab 16 MB werden die Schreibvorgänge nicht verzögert. 16 MB ist der Haltepunkt zwischen FAT12 und FAT16, wenn ich ein Laufwerk unter Windows formatiere. (Hinweis später hinzugefügt: Der FAT12 / FAT16-Haltepunkt hängt jedoch von der Anzahl der Cluster ab, nicht von der absoluten Größe des Dateisystems.)

Bei 16 MB und mehr sendet Windows Prevent/Allow Medium Removalvor dem Schreiben SCSI- Befehle und fordert Sie auf, das Gerät nicht zu entfernen. Der USB-Stick gibt bei diesen Anforderungen tatsächlich einen Fehler zurück (da er keine Entfernung garantieren kann), aber Windows versucht es trotzdem. Die 15 MB und kleineren Traces zeigen keine Prevent/Allow Medium Removal Befehle an.

(Ich habe dieses Problem bei der Verwendung einer Mikrocontroller-Karte entdeckt, die ein winziges FAT-Dateisystem mit Python-Code unterstützt. Wenn der Mikrocontroller einen Schreibvorgang in das Dateisystem erkennt, wartet er etwas, bis der Schreibvorgang abgeschlossen ist, und startet den neu geschriebenen Python-Code automatisch neu und führt ihn aus Der Mikrocontroller hat jedoch aufgrund des verzögerten Schreibens beschädigten Code oder ein beschädigtes Dateisystem gesehen.)

Warum verzögert sich das Schreiben in die FAT so lange, obwohl "Quick Removal" eingestellt ist? Ich kann das Schreiben erzwingen, indem ich ein "Auswerfen" auf dem Laufwerk ausführe, aber das macht das Versprechen von "Schnellentfernung" zunichte. Wenn ich das Laufwerk vorzeitig ziehen würde, hätte es eine falsche FAT-Tabelle. Dies widerspricht der Aussage im folgenden Screenshot, dass "Hardware sicher entfernen" nicht verwendet werden muss. Ist das ein Fehler oder fehlt mir etwas? Gibt es eine Möglichkeit, alle Schreibvorgänge ohne manuelles "Auswerfen" sofort auszuführen?

USB-Laufwerk auf Schnellentfernung eingestellt

Hier ist ein beschnittener Auszug aus einem Wireshark / USBPcap-Trace, der das Problem zeigt. Ich schneide eine vorhandene Datei ab und schreibe dann eine neue Kopie davon. Ich habe Kommentare mit hinzugefügt ###. Die meisten Schreibvorgänge auf das USB-Laufwerk erfolgen etwa 5 Sekunden nach Ablauf der Ablaufverfolgung, der endgültige FAT-Schreibvorgang dauert jedoch erst 26 Sekunden.

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

Ich habe solche Spuren mit einem normalen Flash-Laufwerk und einer Mikrocontroller-Karte generiert, die ein winziges USB-MSC-Laufwerk sowohl unter Windows 7 als auch unter Windows 10 emuliert.

Um ganz klar zu sein, dies ist ein FAT12-formatiertes Laufwerk, das im Windows-Formatierungstool nur "FAT" genannt wird.


1
Bist du nur neugierig Oder stehen Sie vor einem Szenario, in dem Sie ein FAT16-Dateisystem verwenden müssen?
Ich sage Reinstate Monica

2
Ich helfe beim Testen eines Mikrocontroller-Boards (Adafruit Feather M0 und verwandte), auf dem eine Variante von MicroPython (CircuitPython) ausgeführt wird. Es hat ein winziges FAT-Dateisystem, das Python-Code enthält. Aus praktischen Gründen ist die Karte so eingerichtet, dass sie automatisch zurückgesetzt und main.pyähnliche Dateien ausgeführt wird, wenn festgestellt wird, dass die Datei geschrieben wurde. Es dauert eine Weile, bis der Schreibvorgang abgeschlossen ist, aber nicht einige zehn Sekunden. Wir können diesen automatischen Neustart deaktivieren, aber es ist immer noch erforderlich, das Laufwerk "auszuwerfen", um sicherzustellen, dass der Schreibvorgang rechtzeitig abgeschlossen wird. Das Auffordern des Benutzers zum Auswerfen ist ein Ärgernis. das möchten wir vermeiden.
Dan Halbert

Bitte überlegen Sie, zu Beginn Ihrer Frage eine kurze Erklärung zu geben. Es ist ein guter Hintergrundkontext.
Ich sage Reinstate Monica

Guter Vorschlag. Erledigt.
Dan Halbert

Antworten:


4

Möglicherweise habe ich den tatsächlichen Windows-Treibercode gefunden, der das Problem verursacht.

MS nimmt den FAT-Dateisystemtreiber zufällig in ein Paket mit Beispieltreibercode auf. Es gibt mehrere Stellen in diesem Treiber, an denen sich der Treiber, wenn das Dateisystem FAT12 ist, nicht die Mühe macht, das Dirty-Bit zu setzen (möglicherweise gibt es keines für FAT12) oder die FAT-Daten zu löschen.

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 und vielleicht am kritischsten: https://github.com/Microsoft/Windows-driver-samples/blob/master/filesys/fastfat/cleanup.c#L1101

Im letzten Link in cleanup.cwird die FAT nicht gelöscht, wenn das Dateisystem FAT12 ist. Ich denke, dies kann genau das Verhalten verursachen, das ich sehe:

    //
    //  If that worked ok,  then see if we should flush the FAT as well.
    //

    if (NT_SUCCESS(Status) && Fcb && !FatIsFat12( Vcb) && 
        FlagOn( Fcb->FcbState, FCB_STATE_FLUSH_FAT)) {

        Status = FatFlushFat( IrpContext, Vcb);

Im Windows Feedback Hub unter https://aka.ms/btvdog an Microsoft gemeldet (spezielle URL, die im Feedback Hub geöffnet wird).

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.