尽管“快速删除”,Windows仍延迟在小型USB驱动器上写入FAT表


10

我看到在小容量FAT(FAT12)格式的USB闪存驱动器上写入FAT的延迟,即使该驱动器的策略设置为“快速删除”。(我相信这意味着SurpriseRemovalOK标志已设置)。我已经捕获了通过USB发送到驱动器的SCSI命令:立即执行文件截断写操作,之后立即写入整个文件(长2 512字节的扇区),但是在FAT之前有20-90秒的延迟已更新以反映文件写入。

驱动器的大小很大。我进行了测试,并看到大小为15MB或更小的FAT文件系统上的问题。在16MB及更高版本上,写入不会延迟。在Windows中格式化驱动器时,我在使用FAT12和FAT16之间看到了16MB的断点。(稍后会添加注意:但是FAT12 / FAT16断点取决于群集数,而不是绝对文件系统大小)。

在16MB及更大的磁盘上,Windows Prevent/Allow Medium Removal在写入之前发送SCSI 命令,要求不要删除该设备。USB记忆棒实际上在这些请求上返回了失败(因为它不能保证不能删除),但是Windows还是尝试了。15MB及以下的迹线不显示任何 Prevent/Allow Medium Removal命令。

(我在使用支持包含Python代码的微型FAT文件系统的微控制器板时发现了此问题。当微控制器检测到对文件系统的写入时,它会等待写入完成,然后自动重启并运行新编写的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

我已经在Windows 7和Windows 10上使用常规闪存驱动器以及模拟微细USB MSC驱动器的微控制器板生成了这样的跟踪。

请清楚,这是FAT12格式的驱动器,在Windows格式化工具中称为“ FAT”。


1
你只是好奇吗?还是面临着需要使用FAT16文件系统的情况?
我说恢复莫妮卡

2
我正在帮助测试运行MicroPython(CircuitPython)变体的微控制器板(Adafruit Feather M0和相关产品)。它具有一个包含Python代码的微型FAT文件系统。为方便起见,将板卡设置为main.py在检测到已写入文件时自动重置并运行或类似文件。它会延迟一段时间才能完成写入,但不会延迟数十秒。我们可以禁用此自动重启功能,但是仍然有必要“弹出”驱动器以确保及时完成写入。要求用户进行弹出操作很麻烦。我们希望避免这种情况。
丹·哈尔伯特

请考虑在问题的开头进行简短说明。这是一个很好的背景。
我说恢复莫妮卡

好建议。做完了
丹·哈尔伯特

Answers:


4

我可能已经找到导致此问题的实际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

在最后一个链接in中cleanup.c,如果文件系统为FAT12,则不会刷新FAT。我认为这可能正好导致了我所看到的行为:

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

在Windows反馈中心的https://aka.ms/btvdog(在“反馈中心”中打开的特殊URL)报告给Microsoft 。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.