Я бачу затримку запису в FAT на невеликій ємності FAT (FAT12) -форматоване флеш-накопичувач USB, хоча політика для диска встановлена на "Швидке видалення". (Я вважаю, це означає, що SurpriseRemovalOK
прапор встановлений). Я захопив команди SCSI, що надсилаються на накопичувач через USB: запис усікання файлів відбувається негайно, весь файл (2 512-байтних секторів) записується одразу після цього, але тоді перед затримкою FAT затримка 20-90 секунд оновлюється для відображення запису файлу.
Розмір накопичувача є значним. Я протестував і бачу проблеми у файлових системах FAT розміром 15 Мб і менше. З 16 Мб і вище, записи не затримуються. 16 Мб - це точка розриву, яку я бачу між використанням FAT12 та FAT16, коли я форматую диск у Windows. (Примітка додана пізніше: Але точка розриву FAT12 / FAT16 залежить від кількості кластерів, а не від абсолютного розміру файлової системи).
У розмірі 16 Мб і більше Windows надсилає Prevent/Allow Medium Removal
команди SCSI перед записом із проханням не знімати пристрій. USB-накопичувач насправді повертає збій у цих запитах (оскільки він не може гарантувати видалення), але Windows все одно намагається. На 15 Мб і менших слідах не відображаються Prevent/Allow Medium Removal
команди.
(Я виявив цю проблему під час використання плати мікроконтролера, яка підтримує крихітну файлову систему FAT, що містить код Python. Коли мікроконтролер виявить запис у файловій системі, він трохи чекає завершення запису, а потім автоматично перезавантажує і запускає щойно написаний код Python . Але мікроконтролер бачив пошкоджений код або пошкоджену файлову систему через затримку запису.)
Чому запис у FAT затримується так довго, незважаючи на встановлення "Швидкого видалення"? Я можу змусити записати, виконавши "Витягнення" на диску, але це перешкоджає обіцянню "Швидке видалення". Якщо я витягнув диск, він мав би неправильну таблицю FAT. Це заперечує твердження на знімку екрана нижче про те, що не потрібно використовувати "Безпечне видалення обладнання". Це помилка чи я щось пропускаю? Чи є якийсь спосіб змусити всі записи статися негайно без посібника "Витягнення"?
Ось підрізаний витяг із сліду 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
Я створив такі сліди за допомогою звичайної флешки, а також за допомогою плати мікроконтролера, яка імітує крихітний USB-накопичувач MSC як для Windows 7, так і для Windows 10.
Щоб було зрозуміло, це диск із форматом FAT12, що називається "FAT" в інструменті форматування Windows.
main.py
або подібних файлів, коли виявляє, що файл був записаний. Це затримує трохи на завершення запису, але не десятки секунд. Ми можемо відключити цей автоматичний перезапуск, але все-таки потрібно "вийняти" накопичувач, щоб переконатися, що запис завершено своєчасно. Вимагати від користувача виконувати Eject - це неприємність; ми хотіли б цього уникнути.