Windowsは、「クイック削除」にもかかわらず、小さなUSBドライブでのFATテーブルの書き込みを遅らせます


10

ドライブのポリシーが「クイック削除」に設定されているにもかかわらず、小容量のFAT(FAT12)でフォーマットされたUSBフラッシュドライブのFATへの書き込みが遅れているのがわかります。(これはSurpriseRemovalOKフラグが設定されていることを意味すると思います)。USB経由でドライブに送信されたSCSIコマンドをキャプチャしました。ファイルの切り捨て書き込みがすぐに行われ、ファイル全体(2 512バイトセクター長)がその直後に書き込まれますが、FATの前に20〜90秒の遅延があります。ファイルの書き込みを反映するように更新されます。

ドライブのサイズは重要です。私は15MB以下のサイズのFATファイルシステムでテストして問題を確認しました。16MB以上では、書き込みは遅延されません。16MBは、WindowsでドライブをフォーマットするときにFAT12とFAT16を使用するときに目にするブレークポイントです。(後で追加されたメモ:ただし、FAT12 / FAT16ブレークポイントは、ファイルシステムの絶対サイズではなく、クラスターの数に依存します)。

16MB以上では、Windows Prevent/Allow Medium Removalは書き込み前にSCSI コマンドを送信し、デバイスを削除しないように要求します。USBスティックは実際にはこれらの要求に対して失敗を返します(削除を保証できないため)が、Windowsはとにかく試みます。15MB以下のトレースでは Prevent/Allow Medium Removalコマンドは表示されません

(Pythonコードを含む小さなFATファイルシステムをサポートするマイクロコントローラーボードを使用しているときにこの問題を発見しました。マイクロコントローラーがファイルシステムへの書き込みを検出すると、書き込みが完了するのを少し待ってから、新しく書き込まれたPythonコードを自動的に再起動して実行します。しかし、マイクロコントローラーは、書き込みの遅延が原因で、破損したコードまたは破損したファイルシステムを検出していました。)

「クイック削除」が設定されているにもかかわらず、FATへの書き込みが非常に長く遅延するのはなぜですか?ドライブで「イジェクト」を実行することで書き込みを強制できますが、これは「クイック削除」の約束を破ります。ドライブを早めに引っ張ると、FATテーブルが不正確になります。これは、「ハードウェアの安全な取り外し」を使用する必要がないという以下のスクリーンショットの説明とは異なります。これはバグですか、それとも何か不足していますか?すべての書き込みを手動の「イジェクト」なしですぐに強制的に実行する方法はありますか?

クイック取り外しに設定されたUSBドライブ

これは、Wireshark / USBPcapトレースからの剪定抽出で、問題を示しています。既存のファイルを切り捨ててから、その新しいコピーを書き込みます。にコメントを追加しました###。USBドライブへの書き込みのほとんどは、トレースの約5秒後に行われますが、最後のFAT書き込みは26秒まで行われません。

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

Windows 7とWindows 10の両方で、通常のフラッシュドライブと、小さなUSB MSCドライブをエミュレートするマイクロコントローラーボードを使用して、このようなトレースを生成しました。

明確にするために、これはFAT12でフォーマットされたドライブで、Windowsのフォーマットツールでは単に「FAT」と呼ばれています。


1
気になる?または、FAT16ファイルシステムを使用する必要があるシナリオに直面していますか?
私はモニカを

2
MicroPython(CircuitPython)のバリアントを実行するマイクロコントローラーボード(Adafruit Feather M0および関連)のテストを支援しています。Pythonコードを含む小さなFATファイルシステムがあります。便宜上、ボードはmain.py、ファイルが書き込まれたことを検出すると、自動リセットして実行するように設定されています。書き込みが完了するまで少し遅れますが、数十秒はかかりません。この自動再起動を無効にすることもできますが、書き込みがタイムリーに完了するようにするには、ドライブを「イジェクト」する必要があります。ユーザーに取り出しを要求するのは面倒です。それは避けたいです。
Dan Halbert 2017

質問の最初に、これについての簡単な説明を編集することを検討してください。持っているのは良い背景コンテキストです。
私はモニカを

良い提案。できました。
Dan Halbert 2017

回答:


4

問題の原因となっている実際のWindowsドライバーコードを見つけた可能性があります。

MSはたまたま、サンプルドライバーコードのパッケージにFATファイルシステムドライバーを含めています。そのドライバーにはいくつかの場所があり、ファイルシステムがFAT12の場合、ドライバーはダーティビットを設定する(FAT12にはない)か、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 そしておそらく最も重要:https : //github.com/Microsoft/Windows-driver-samples/blob/master/filesys/fastfat/cleanup.c#L1101

最後のリンクのではcleanup.c、ファイルシステムがFAT12の場合、FATはフラッシュされません。私はこれが私が見る行動を正確に引き起こしていると思います:

    //
    //  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);

https://aka.ms/btvdog(フィードバックハブで開く特別なURL)のWindowsフィードバックハブでMicrosoftに報告されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.