9

Я вижу отложенные записи в FAT на USB-флэш-накопителе с малой емкостью FAT(FAT12), даже если для политики задано "Быстрое удаление". (Я полагаю, это означает, что установлен флаг SurpriseRemovalOK ). Я перехватил команды SCSI, отправленные на диск через USB: запись усечения файла происходит немедленно, весь файл (2 512-байтовых секторов) записывается сразу после этого, но затем перед FAT происходит задержка в 20-90 секунд обновляется, чтобы отразить запись файла.

Размер диска значительный. Я проверил и вижу проблемы на файловых системах FAT размером 15 МБ и меньше. На 16 МБ и выше запись не задерживается. 16 МБ - это точка останова между использованием FAT12 и FAT16 при форматировании диска в Windows. (Примечание добавлено позже: Но точка останова FAT12/FAT16 зависит от количества кластеров, а не от абсолютного размера файловой системы).

На 16 МБ и больше Windows отправляет команды SCSI Prevent/Allow Medium Removal перед записью с просьбой не удалять устройство. USB-флешка на самом деле возвращает ошибку при этих запросах (потому что она не может гарантировать удаление), но Windows все равно пытается. Следы размером 15 МБ и меньше не показывают команды « Prevent/Allow Medium Removal .

(Я обнаружил эту проблему при использовании платы микроконтроллера, которая поддерживает крошечную файловую систему FAT, содержащую код Python. Когда микроконтроллер обнаруживает запись в файловую систему, он немного ждет завершения записи, а затем автоматически перезапускает и запускает вновь написанный код Python. Но микроконтроллер обнаружил поврежденный код или поврежденную файловую систему из-за отложенной записи.)

Почему запись в FAT задерживается так долго, несмотря на установленное "Быстрое удаление"? Я могу форсировать запись, выполнив "Извлечение" на диске, но это не соответствует обещанию "Быстрое удаление". Если бы я выдернул диск раньше, у него была бы неправильная таблица FAT. Это противоречит утверждению на снимке экрана ниже о том, что не нужно использовать "Безопасное извлечение оборудования". Это ошибка или я что-то упустил? Есть ли способ заставить все записи происходить немедленно без ручного "извлечения"?

USB-накопитель настроен на быстрое удаление

Вот сокращенная выдержка из трассировки 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.

1 ответ1

3

Возможно, я нашел фактический код драйвера 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. Я думаю, что это может быть причиной именно того поведения, которое я вижу:

    //
    //  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);

Об этом сообщает Microsoft в Windows Feedback Hub по адресу https://aka.ms/btvdog (специальный URL, который открывается в Feedback Hub).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .