Windows는“빠른 제거”에도 불구하고 작은 USB 드라이브에 FAT 테이블 쓰기를 지연시킵니다


10

드라이브 정책이 "빠른 제거"로 설정되어 있어도 소용량 FAT (FAT12) 형식의 USB 플래시 드라이브에서 FAT에 대한 쓰기 지연이 발생합니다. (이것은 SurpriseRemovalOK깃발이 설정 되었음을 의미한다고 생각합니다 ). USB를 통해 드라이브로 전송되는 SCSI 명령을 캡처했습니다. 파일 잘림 쓰기가 즉시 발생하고 전체 파일 (2 512 바이트 섹터 길이)이 그 직후에 기록되지만 FAT보다 20-90 초 지연됩니다. 파일 쓰기를 반영하도록 업데이트됩니다.

드라이브의 크기가 중요합니다. 크기가 15MB 이하인 FAT 파일 시스템에서 테스트 한 결과 문제가 있습니다. 16MB 이상에서는 쓰기가 지연되지 않습니다. 16MB는 Windows에서 드라이브를 포맷 할 때 FAT12와 FAT16을 사용할 때 나타나는 중단 점입니다. (나중에 추가 된 참고 사항 : 그러나 FAT12 / FAT16 중단 점은 절대 파일 시스템 크기가 아니라 클러스터 수에 따라 다릅니다.)

16MB 이상에서 Windows는 Prevent/Allow Medium Removal쓰기 전에 SCSI 명령을 전송 하여 장치를 제거하지 않도록 요청합니다. USB 스틱은 실제로 이러한 요청에서 실패를 반환하지만 (제거가 보장되지 않기 때문에) Windows는 어쨌든 시도합니다. 15MB 이하의 트레이스는 명령을 표시 하지 않습니다 Prevent/Allow Medium Removal .

(파이썬 코드를 포함하는 작은 FAT 파일 시스템을 지원하는 마이크로 컨트롤러 보드를 사용하는 동안이 문제를 발견했습니다. 마이크로 컨트롤러가 파일 시스템에 대한 쓰기를 감지하면 쓰기가 완료 될 때까지 약간 기다렸다가 자동으로 다시 시작하여 새로 작성된 Python 코드를 실행합니다. 그러나 마이크로 컨트롤러는 쓰기 지연으로 인해 손상된 코드 또는 파일 시스템이 손상되었습니다.)

"빠른 제거"가 설정되어 있는데도 FAT에 대한 쓰기가 왜 그렇게 오래 지연됩니까? 드라이브에서 "이젝트"를 수행하여 쓰기를 강제 할 수 있지만 "빠른 제거"의 가능성을 상실합니다. 드라이브를 일찍 꺼내면 잘못된 FAT 테이블이 생깁니다. 아래의 스크린 샷에서 "하드웨어 안전하게 제거"를 사용할 필요가 없다는 내용입니다. 이것은 버그입니까, 아니면 뭔가 빠졌습니까? 수동 "Eject"없이 모든 쓰기를 즉시 수행 할 수있는 방법이 있습니까?

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 드라이브를 에뮬레이트하는 마이크로 컨트롤러 보드를 사용하여 이와 같은 추적을 생성했습니다.

분명히, 이것은 Windows 포맷 도구에서 "FAT"라고하는 FAT12 포맷 드라이브입니다.


1
그냥 궁금하십니까? 아니면 FAT16 파일 시스템을 사용해야하는 시나리오에 직면하고 있습니까?
나는

2
MicroPython (CircuitPython)의 변형을 실행하는 마이크로 컨트롤러 보드 (Adafruit Feather M0 및 관련)를 테스트하고 있습니다. 파이썬 코드를 포함하는 작은 FAT 파일 시스템이 있습니다. 편의상 보드는 main.py파일이 작성된 것을 감지하면 자동 재설정 및 실행 또는 유사한 파일로 설정됩니다. 쓰기가 완료 될 때까지 지연되지만 수십 초는 아닙니다. 이 자동 재시작을 비활성화 할 수 있지만 적시에 쓰기가 완료되도록하려면 드라이브를 "꺼내기"해야합니다. 사용자에게 꺼내기를 요구하는 것은 성가신 일입니다. 우리는 그것을 피하고 싶습니다.
Dan Halbert

질문의 시작 부분에 대한 간단한 설명을 편집 해보십시오. 좋은 배경 컨텍스트입니다.
나는 말한다 Reinstate Monica

좋은 제안. 끝난.
Dan Halbert

답변:


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

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에보고했습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.