Я бачу затримку запису в 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 - це неприємність; ми хотіли б цього уникнути.
