Widzę opóźnione zapisy w systemie FAT na sformatowanym dysku flash USB o małej pojemności (FAT12), mimo że dla tego dysku wybrano ustawienie „Szybkie usuwanie”. (Wierzę, że to oznacza, że SurpriseRemovalOK
flaga jest ustawiona). Przechwyciłem polecenia SCSI wysyłane na dysk przez USB: zapisy obcinania plików odbywają się natychmiast, cały plik (długość 2 512 bajtów sektorów) jest zapisywany natychmiast po tym, ale potem jest FAT o 20-90 sekund jest aktualizowany, aby odzwierciedlić zapis pliku.
Rozmiar dysku jest znaczący. Testowałem i widzę problemy z systemami plików FAT o rozmiarze 15 MB i mniejszym. Przy 16 MB i więcej zapisy nie są opóźniane. 16 MB to punkt przerwania, który widzę między użyciem FAT12 i FAT16 podczas formatowania dysku w systemie Windows. (Uwaga dodana później: Ale punkt przerwania FAT12 / FAT16 zależy od liczby klastrów, a nie od absolutnego rozmiaru systemu plików).
W wersjach 16 MB i większych system Windows wysyła Prevent/Allow Medium Removal
polecenia SCSI przed zapisem, prosząc, aby urządzenie nie zostało usunięte. Pamięć USB faktycznie zwraca błąd w przypadku tych żądań (ponieważ nie może zagwarantować braku usunięcia), ale system Windows mimo to próbuje. Ślady 15 MB i mniejsze nie pokazują Prevent/Allow Medium Removal
poleceń.
(Odkryłem ten problem podczas korzystania z płytki mikrokontrolera, która obsługuje mały system plików FAT zawierający kod Python. Gdy mikrokontroler wykryje zapis w systemie plików, czeka trochę na zakończenie zapisu, a następnie automatycznie uruchamia się ponownie i uruchamia nowo napisany kod Python Ale mikrokontroler widział uszkodzony kod lub uszkodzony system plików z powodu opóźnionego zapisu.)
Dlaczego zapis do FAT jest tak opóźniony pomimo ustawienia „Szybkie usuwanie”? Mogę wymusić zapisy, wykonując polecenie „Wysuń” na dysku, ale to obala obietnicę „Szybkie usunięcie”. Gdybym wcześniej wyciągnął dysk, miałby on niepoprawną tabelę FAT. To zaprzecza stwierdzeniu na zrzucie ekranu poniżej, że nie trzeba używać „Bezpiecznego usuwania sprzętu”. Czy to błąd, czy coś brakuje? Czy istnieje sposób, aby zmusić wszystkie zapisy do natychmiastowego wykonania bez ręcznego „Wysuń”?
Oto przycięty fragment ze śladu Wireshark / USBPcap pokazujący problem. Obcinam istniejący plik, a następnie zapisuję jego nową kopię. Dodałem komentarze do ###
. Większość zapisów na dysku USB odbywa się w ciągu około 5 sekund, ale ostateczny zapis FAT trwa dopiero po 26 sekundach.
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
Generowałem takie ślady za pomocą zwykłego dysku flash, a także płytki mikrokontrolera, która emuluje mały dysk USB MSC, zarówno w systemie Windows 7, jak i Windows 10.
Dla jasności jest to dysk sformatowany w systemie FAT12, zwany po prostu „FAT” w narzędziu formatującym Windows.
źródło
main.py
lub podobnych plików po wykryciu, że plik został zapisany. Trwa trochę opóźnienie zapisu, ale nie kilkadziesiąt sekund. Możemy wyłączyć to automatyczne restartowanie, ale nadal konieczne jest „wysunięcie” napędu, aby mieć pewność, że zapis zostanie zakończony w odpowiednim czasie. Wymaganie od użytkownika wysunięcia jest uciążliwe; chcielibyśmy tego uniknąć.Odpowiedzi:
Mogłem znaleźć rzeczywisty kod sterownika Windows, który powoduje problem.
Zdarza się, że MS dołącza sterownik systemu plików FAT do pakietu przykładowego kodu sterownika. W tym sterowniku jest kilka miejsc, w których jeśli systemem plików jest FAT12, sterownik nie będzie się starał robić czegoś takiego jak ustawienie brudnego bitu (być może nie ma FAT12) lub opróżnianie danych 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 i może najbardziej krytycznie: https://github.com/Microsoft/Windows-driver-samples/blob/master/filesys/fastfat/cleanup.c#L1101
W ostatnim łączu
cleanup.c
wewnątrz FAT nie jest opróżniany, jeśli systemem plików jest FAT12. Myślę, że może to powodować dokładnie takie zachowanie, jakie widzę:Zgłoszone do Microsoft w Centrum opinii Windows na https://aka.ms/btvdog (specjalny adres URL, który otwiera się w Centrum opinii).
źródło