Windows menunda menulis tabel FAT pada drive USB kecil meskipun “Penghapusan cepat”

10

Saya melihat penundaan penulisan ke FAT pada USB flash drive yang diformat FAT (FAT12) walaupun kebijakan untuk drive tersebut diatur ke "Penghapusan Cepat". (Saya percaya ini berarti SurpriseRemovalOKbendera disetel). Saya telah menangkap perintah SCSI yang dikirim ke drive melalui USB: pemotongan file write terjadi segera, seluruh file (panjang 2 sektor 512-byte) ditulis segera setelah itu, tetapi kemudian ada penundaan 20-90 detik sebelum FAT diperbarui untuk mencerminkan penulisan file.

Ukuran drive signifikan. Saya telah menguji dan melihat masalah pada sistem file FAT ukuran 15MB dan lebih kecil. Pada 16MB ke atas, penulisan tidak tertunda. 16MB adalah breakpoint yang saya lihat antara menggunakan FAT12 dan FAT16 ketika saya memformat drive di Windows. (Catatan ditambahkan kemudian: Tapi breakpoint FAT12 / FAT16 tergantung pada jumlah cluster, bukan ukuran sistem file absolut).

Pada 16MB dan lebih besar, Windows mengirim Prevent/Allow Medium Removalperintah SCSI sebelum menulis, meminta perangkat tidak dihapus. Stik USB sebenarnya mengembalikan kegagalan pada permintaan ini (karena tidak dapat menjamin tidak ada penghapusan), tetapi Windows tetap mencoba. Jejak 15MB dan lebih kecil tidak menunjukkan Prevent/Allow Medium Removalperintah.

(Saya menemukan masalah ini saat menggunakan papan mikrokontroler yang mendukung sistem file FAT kecil yang berisi kode Python. Ketika mikrokontroler mendeteksi penulisan ke sistem file, ia menunggu sedikit waktu untuk menyelesaikan penulisan dan kemudian secara otomatis memulai ulang dan menjalankan kode Python yang baru ditulis Tetapi mikrokontroler melihat kode yang rusak atau filesystem yang rusak karena keterlambatan penulisan.)

Mengapa penulisan ke FAT tertunda begitu lama, meskipun "Penghapusan Cepat" diatur? Saya dapat memaksa menulis dengan melakukan "Keluarkan" pada drive tetapi itu mengalahkan janji "Penghapusan Cepat". Jika saya menarik drive lebih awal itu akan memiliki tabel FAT yang salah. Ini memungkiri pernyataan dalam cuplikan layar di bawah ini tentang tidak harus menggunakan "Safely Remove Hardware". Apakah ini bug atau saya melewatkan sesuatu? Apakah ada cara untuk memaksa semua penulisan terjadi segera tanpa "Eject" manual?

Drive USB diatur ke Penghapusan Cepat

Berikut adalah ekstrak yang telah dipangkas dari jejak Wireshark / USBPcap yang menunjukkan masalah ini. Saya memotong file yang sudah ada dan kemudian menulis salinannya. Saya telah menambahkan komentar dengan ###. Sebagian besar penulisan ke drive USB berlangsung sekitar 5 detik ke dalam jejak, tetapi penulisan FAT terakhir tidak sampai 26 detik.

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

Saya telah membuat jejak seperti ini menggunakan flash drive biasa dan juga dengan papan mikrokontroler yang mengemulasi drive MSC USB kecil, pada Windows 7 dan windows 10.

Untuk lebih jelasnya, ini adalah drive yang diformat FAT12, hanya disebut "FAT" di alat pemformatan Windows.

Dan Halbert
sumber
1
Apakah kamu hanya ingin tahu? Atau apakah Anda menghadapi skenario di mana Anda diminta untuk menggunakan sistem file FAT16?
Saya katakan Reinstate Monica
2
Saya membantu untuk menguji papan mikrokontroler (Adafruit Feather M0 dan yang terkait) menjalankan varian MicroPython (CircuitPython). Ini memiliki sistem file FAT kecil yang berisi kode Python. Sebagai kenyamanan, board diatur untuk reset otomatis dan menjalankan main.pyatau file serupa ketika mendeteksi file telah ditulis. Menunda sedikit untuk menyelesaikan menulis, tetapi tidak puluhan detik. Kami dapat menonaktifkan restart otomatis ini, tetapi masih perlu "Keluarkan" drive untuk memastikan penulisan selesai tepat waktu. Membutuhkan pengguna untuk melakukan Eject adalah gangguan; kami ingin menghindari itu.
Dan Halbert
Harap pertimbangkan untuk mengedit di awal pertanyaan Anda, penjelasan singkat tentang ini. Ini konteks latar belakang yang bagus untuk dimiliki.
Saya katakan Reinstate Monica
Saran yang bagus Selesai
Dan Halbert

Jawaban:

4

Saya mungkin telah menemukan kode driver Windows aktual yang menyebabkan masalah.

MS kebetulan memasukkan driver sistem file FAT dalam paket kode driver sampel. Ada beberapa tempat di driver itu di mana, jika filesystem FAT12, driver tidak akan repot untuk melakukan sesuatu seperti mengatur bit kotor (mungkin tidak ada untuk FAT12) atau menyiram data 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 dan mungkin paling kritis: https://github.com/Microsoft/Windows-driver-samples/blob/master/filesys/fastfat/cleanup.c#L1101

Di tautan terakhir, dalam cleanup.c, FAT tidak memerah jika sistem file FAT12. Saya pikir ini mungkin menyebabkan perilaku yang saya lihat:

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

Dilaporkan ke Microsoft di Windows Feedback Hub di https://aka.ms/btvdog (URL khusus yang terbuka di Feedback Hub).

Dan Halbert
sumber