Tôi đang thấy sự chậm trễ ghi vào FAT trên ổ flash USB có định dạng FAT (FAT12) dung lượng nhỏ mặc dù chính sách cho ổ đĩa được đặt thành "Loại bỏ nhanh". (Tôi tin rằng điều này có nghĩa là SurpriseRemovalOK
cờ được đặt). Tôi đã bắt được các lệnh SCSI được gửi tới ổ đĩa qua USB: quá trình ghi tệp bị cắt xảy ra ngay lập tức, toàn bộ tệp (2 cung dài 512 byte) được ghi ngay sau đó, nhưng sau đó có độ trễ 20-90 giây trước FAT được cập nhật để phản ánh tập tin ghi.
Kích thước của ổ đĩa là đáng kể. Tôi đã thử nghiệm và thấy các sự cố trên hệ thống tệp FAT có kích thước 15MB và nhỏ hơn. Trên 16MB trở lên, việc ghi không bị trì hoãn. 16MB là điểm dừng tôi thấy giữa việc sử dụng FAT12 và FAT16 khi tôi định dạng ổ đĩa trong Windows. (Lưu ý thêm vào sau: Nhưng điểm dừng của FAT12 / FAT16 phụ thuộc vào số lượng cụm chứ không phải kích thước hệ thống tệp tuyệt đối).
Trên 16 MB và lớn hơn, Windows sẽ gửi các Prevent/Allow Medium Removal
lệnh SCSI trước khi ghi, yêu cầu không xóa thiết bị. Thanh USB thực sự trả về thất bại cho các yêu cầu này (vì nó không thể đảm bảo không loại bỏ), nhưng dù sao thì Windows vẫn cố gắng. Các dấu vết 15MB và nhỏ hơn cho thấy không có Prevent/Allow Medium Removal
lệnh.
(Tôi đã phát hiện ra vấn đề này trong khi sử dụng bảng vi điều khiển hỗ trợ hệ thống tệp FAT nhỏ chứa mã Python. Khi vi điều khiển phát hiện ghi vào hệ thống tệp, nó đợi một chút để ghi hoàn thành rồi tự động khởi động lại và chạy mã Python mới được viết . Nhưng vi điều khiển đã thấy mã bị hỏng hoặc hệ thống tệp bị hỏng do ghi chậm.)
Tại sao việc ghi vào FAT bị trì hoãn quá lâu, mặc dù "Loại bỏ nhanh" được đặt? Tôi có thể buộc viết bằng cách thực hiện "Đẩy" trên ổ đĩa nhưng điều đó đánh bại lời hứa "Loại bỏ nhanh". Nếu tôi kéo ổ đĩa sớm, nó sẽ có một bảng FAT không chính xác. Điều này tin rằng tuyên bố trong ảnh chụp màn hình bên dưới về việc không phải sử dụng "Phần cứng loại bỏ an toàn". Đây có phải là một lỗi hoặc tôi đang thiếu một cái gì đó? Có cách nào để buộc tất cả các ghi được xảy ra ngay lập tức mà không có "Eject" thủ công không?
Đây là một trích xuất được cắt tỉa từ dấu vết Wireshark / USBPcap cho thấy vấn đề. Tôi cắt một tập tin hiện có và sau đó viết một bản sao mới của nó. Tôi đã thêm ý kiến với ###
. Hầu hết các lần ghi vào ổ USB diễn ra trong khoảng 5 giây vào dấu vết, nhưng lần ghi FAT cuối cùng không kéo dài đến 26 giây.
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
Tôi đã tạo ra các dấu vết như thế này bằng cách sử dụng ổ đĩa flash thông thường và với bảng vi điều khiển mô phỏng ổ USB USB nhỏ, trên cả Windows 7 và windows 10.
Nói rõ hơn, đây là một ổ đĩa có định dạng FAT12, chỉ được gọi là "FAT" trong công cụ định dạng Windows.
main.py
hoặc các tệp tương tự khi phát hiện tệp đã được ghi. Nó trì hoãn một chút để ghi hoàn thành, nhưng không phải hàng chục giây. Chúng tôi có thể vô hiệu hóa tự động khởi động lại này, nhưng vẫn cần phải "Đẩy" ổ đĩa để đảm bảo việc ghi hoàn thành một cách kịp thời. Yêu cầu người dùng thực hiện Eject là một sự phiền toái; chúng tôi muốn tránh điều đó