Я вижу отложенные записи в FAT на USB-флэш-накопителе с малой емкостью FAT (FAT12), даже если для политики задано «Быстрое удаление». (Я считаю, что это означает, что 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 является неприятностью; мы хотели бы избежать этого.Ответы:
Возможно, я нашел фактический код драйвера Windows, который вызывает проблему.
MS включает драйвер файловой системы FAT в пакет примера кода драйвера. В этом драйвере есть несколько мест, где, если файловая система FAT12, драйвер не потрудится сделать что-то вроде установки грязного бита (возможно, его нет для FAT12) или сброса данных 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 и, возможно, наиболее критично: https://github.com/Microsoft/Windows-driver-samples/blob/master/filesys/fastfat/cleanup.c#L1101
В последней ссылке в
cleanup.c
FAT не сбрасывается, если файловая система FAT12. Я думаю, что это может быть причиной именно того поведения, которое я вижу:Об этом сообщает Microsoft в Windows Feedback Hub по адресу https://aka.ms/btvdog (специальный URL, который открывается в Feedback Hub).
источник