O Windows atrasa a gravação da tabela FAT em uma pequena unidade USB, apesar da "remoção rápida"

8

Estou vendo gravações atrasadas no FAT em uma unidade flash USB formatada em FAT (FAT12) de pequena capacidade, embora a diretiva da unidade esteja definida como "Remoção rápida". (Eu acredito que isso significa que o sinalizador SurpriseRemovalOK está definido). Capturei os comandos SCSI enviados para a unidade através de USB: as gravações de truncamento de arquivo acontecem imediatamente, o arquivo inteiro (2 setores de 512 bytes) é gravado imediatamente depois disso, mas há um atraso de 20 a 90 segundos antes do FAT é atualizado para refletir a gravação do arquivo.

O tamanho da unidade é significativo. Eu testei e vi problemas em sistemas de arquivos FAT de 15MB ou menos. Em 16MB ou mais, as gravações não são atrasadas. 16MB é o ponto de interrupção que vejo entre usar FAT12 e FAT16 quando formatar uma unidade no Windows. (Nota adicionada posteriormente: Mas o breakpoint FAT12 / FAT16 depende do número de clusters, não do tamanho absoluto do sistema de arquivos).

Em 16 MB ou mais, o Windows envia comandos SCSI Prevent/Allow Medium Removal antes de gravar, solicitando que o dispositivo não seja removido. O pendrive na verdade retorna falhas nessas solicitações (porque não pode garantir nenhuma remoção), mas o Windows tenta mesmo assim. Os traços de 15MB e menores mostram os comandos no Prevent/Allow Medium Removal .

(Eu descobri esse problema ao usar uma placa microcontroladora que suporta um minúsculo sistema de arquivos FAT contendo código Python. Quando o microcontrolador detecta uma gravação no sistema de arquivos, ele espera um pouco para que a gravação seja concluída e então reinicia automaticamente e executa código Python escrito, mas o microcontrolador estava vendo código corrompido ou um sistema de arquivos corrompido devido à gravação atrasada.)

Por que o write to the FAT atrasou tanto tempo, apesar de "Quick Removal" estar sendo definido? Eu posso forçar as gravações fazendo um "Eject" no drive mas isso derrota a promessa de " Remoção Rápida ". Se eu puxasse a unidade cedo, teria uma tabela FAT incorreta. Isso desmente a afirmação na tela abaixo sobre não ter que usar "Remover hardware com segurança". Isso é um bug ou estou faltando alguma coisa? Existe alguma maneira de forçar todas as gravações para acontecer imediatamente sem um manual "Eject"?

AquiestáumextratopodadodeumrastreamentoWireshark/USBPcapmostrandooproblema.Eutruncarumarquivoexistentee,emseguida,escreverumanovacópiadele.Adicioneicomentárioscom###.AmaioriadasgravaçõesnaunidadeUSBocorreemtornode5segundosnotraçado,masagravaçãofinaldoFATnãoocorreaté26segundos.

No.TimeSourceDestinationProtocolLengthInfo###writedirectoryentrytotruncatefile135.225586host1.2.2USBMS58SCSI:Write(10)LUN:0x00(LBA:0x00000041,Len:8)145.225838host1.2.2USB4123URB_BULKout###writeFATentriestotruncatefile165.230488host1.2.2USBMS58SCSI:Write(10)LUN:0x00(LBA:0x0000003b,Len:1)175.230707host1.2.2USB539URB_BULKout195.235110host1.2.2USBMS58SCSI:Write(10)LUN:0x00(LBA:0x0000003e,Len:1)205.235329host1.2.2USB539URB_BULKout###writedirectoryentryfor225.252672host1.2.2USBMS58SCSI:Write(10)LUN:0x00(LBA:0x00000041,Len:8)235.252825host1.2.2USB4123URB_BULKout###writeoutfiledata(2sectorsof512bytes)255.257416host1.2.2USBMS58SCSI:Write(10)LUN:0x00(LBA:0x000000c1,Len:2)265.257572host1.2.2USB1051URB_BULKout###20seconddelay###finally,writeFATentriestoindicateusedsectors7926.559964host1.2.2USBMS58SCSI:Write(10)LUN:0x00(LBA:0x0000003b,Len:1)8026.560191host1.2.2USB539URB_BULKout8226.560834host1.2.2USBMS58SCSI:Write(10)LUN:0x00(LBA:0x0000003e,Len:1)8326.560936host1.2.2USB539URB_BULKout

EugeravatraçoscomoesteusandoumflashdriveregularetambémcomumaplacademicrocontroladorqueemulaumapequenaunidadeUSBMSC,tantonoWindows7quantonoWindows10.

Sóparaesclarecer,estaéumaunidadeformatadaemFAT12,chamadaapenasde"FAT" na ferramenta de formatação do Windows.

    
por Dan Halbert 09.04.2017 / 02:51

1 resposta

2

Eu posso ter encontrado o código real do driver do Windows que está causando o problema.

O MS inclui o driver do sistema de arquivos FAT em um pacote de código de driver de exemplo. Existem vários lugares nesse driver em que, se o sistema de arquivos for FAT12, o driver não se incomodará em fazer algo como configurar o bit sujo (talvez não haja nenhum para o FAT12) ou liberar os dados do FAT.

link link e talvez mais criticamente: link

No último link, em cleanup.c , o FAT não é liberado se o sistema de arquivos for FAT12. Acho que isso pode estar causando exatamente o comportamento que vejo:

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

Relatado à Microsoft no Windows Feedback Hub, no link (URL especial que é aberto no Hub de comentários).

    
por 27.04.2017 / 06:36