Windows, "Hızlı kaldırma" işlemine rağmen küçük USB sürücüsünde FAT tablosu yazmayı geciktiriyor


10

Sürücünün ilkesi "Hızlı Kaldırma" olarak ayarlanmış olsa da, küçük kapasiteli FAT (FAT12) biçimli bir USB flash sürücüde FAT'a gecikmeli yazmalar görüyorum. (Sanırım bu SurpriseRemovalOKbayrak ayarlanmış demektir ). Sürücüye USB üzerinden gönderilen SCSI komutlarını yakaladım: dosya kesme işlemleri hemen gerçekleşiyor, tüm dosya (2 512 bayt sektör uzunluğunda) bundan hemen sonra yazılıyor, ancak FAT'tan önce 20-90 saniye gecikme var dosya yazma yansıtmak için güncellenir.

Sürücünün boyutu önemlidir. 15MB ve daha küçük FAT dosya sistemlerinde test yaptım ve sorunları gördüm. 16MB ve üstü sürümlerde yazma işlemleri gecikmez. 16MB, Windows'ta bir sürücüyü biçimlendirirken FAT12 ve FAT16 kullanma arasında gördüğüm kesme noktasıdır. (Daha sonra not eklendi: Ancak FAT12 / FAT16 kesme noktası, mutlak dosya sistemi boyutuna değil, küme sayısına bağlıdır).

16MB ve daha büyük sürümlerde, Windows Prevent/Allow Medium Removalyazmadan önce SCSI komutları göndererek cihazın kaldırılmamasını ister. USB bellek aslında bu isteklerde hata veriyor (çünkü kaldırmayı garanti edemiyor), ancak Windows yine de deniyor. 15MB ve daha küçük izleri göstermek hiçbir Prevent/Allow Medium Removal komutları.

(Python kodu içeren küçük bir FAT dosya sistemini destekleyen bir mikrodenetleyici kartı kullanırken bu sorunu keşfettim. Mikrodenetleyici dosya sistemine bir yazma algıladığında, yazma işleminin tamamlanması için biraz bekler ve sonra yeni yazılan Python kodunu otomatik olarak yeniden başlatır ve çalıştırır Ancak mikrodenetleyici gecikmeli yazma nedeniyle bozuk kod veya bozuk bir dosya sistemi görüyordu.)

"Hızlı Kaldırma" ayarlanmasına rağmen, FAT'ye yazma neden bu kadar uzun gecikmeli? Sürücüde bir "Çıkar" yaparak yazma işlemlerini zorlayabilirim, ancak bu "Hızlı Kaldırma" vaadini yener. Sürücüyü erken çekersem, yanlış bir FAT tablosu olurdu. Bu, aşağıdaki ekran görüntüsünde "Donanımı Güvenle Kaldır" ın kullanılması gerekmediğine ilişkin ifadeye inanmaktadır. Bu bir hata mı yoksa bir şey mi kaçırıyorum? Tüm yazma işlemlerini manuel olarak "Çıkar" olmadan hemen yapmaya zorlamanın bir yolu var mı?

Hızlı Çıkarmaya ayarlanmış USB sürücü

İşte sorunu gösteren bir Wireshark / USBPcap izlemesinden budanmış bir alıntı. Varolan bir dosyayı kısaltıp yeni bir kopyasını yazıyorum. İle yorum ekledim ###. USB sürücüye yazılan yazıların çoğu izlemeye yaklaşık 5 saniye sürüyor, ancak son FAT yazma işlemi 26 saniyeye kadar yapılmıyor.

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

Hem normal bir flash sürücü kullanarak hem de Windows 7 ve Windows 10'da küçük bir USB MSC sürücüsünü taklit eden bir mikrodenetleyici kartı ile böyle izler oluşturdum.

Açıkçası, bu Windows biçimlendirme aracında "FAT" olarak adlandırılan FAT12 biçimli bir sürücüdür.


1
Sadece merak ediyor musun? Yoksa FAT16 dosya sistemi kullanmanız gereken bir senaryo ile mi karşı karşıyasınız?
Ben Reinstate Monica

2
MicroPython (CircuitPython) bir varyantı çalıştıran bir mikrodenetleyici kartı (Adafruit Feather M0 ve ilgili) test etmeye yardımcı oluyorum. Python kodu içeren küçük bir FAT dosya sistemine sahiptir. Kolaylık olması açısından, kart otomatik olarak sıfırlanacak ve main.pydosyanın yazıldığını algıladığında veya benzeri dosyaları çalıştıracak şekilde ayarlanmıştır . Yazmanın tamamlanması için biraz geciktirir, ancak onlarca saniye değil. Bu otomatik yeniden başlatmayı devre dışı bırakabiliriz, ancak yazma işleminin zamanında tamamlandığından emin olmak için sürücüyü "Çıkarmak" yine de gereklidir. Kullanıcının bir Çıkarma yapmasını istemek bir sıkıntıdır; bundan kaçınmak istiyoruz.
Dan Halbert

Lütfen sorunuzun başlangıcında bunun kısa bir açıklamasını düzenlemeyi düşünün. Sahip olmak iyi bir arka plan bağlamı.
Reinstate Monica

İyi öneri. Bitti.
Dan Halbert

Yanıtlar:


4

Soruna neden olan gerçek Windows sürücü kodunu bulmuş olabilirim.

MS, FAT dosya sistemi sürücüsünü bir örnek sürücü kodu paketine ekler. Bu sürücüde, dosya sistemi FAT12 ise, sürücünün kirli biti ayarlamak (belki FAT12 için hiçbiri yoktur) veya FAT verilerini temizlemek gibi bir şey yapmak için uğraşmayacağı birkaç yer vardır.

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 ve belki de en önemlisi: https://github.com/Microsoft/Windows-driver-samples/blob/master/filesys/fastfat/cleanup.c#L1101

Son bağlantıda, cleanup.cdosya sistemi FAT12 ise, FAT içinde temizlenmez. Bunun tam olarak gördüğüm davranışa neden olabileceğini düşünüyorum:

    //
    //  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 adresindeki Windows Geri Bildirim Merkezi'nde (Geri Bildirim Merkezi'nde açılan özel URL) Microsoft'a bildirildi .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.