FatFs bridges: build a cluster link map on open - #194
Conversation
Without one, every backward f_lseek walks the FAT chain again from the file's first cluster - and every COMPRESSION_SELF hunk is a backward seek, to an earlier hunk the image references instead of storing twice. The cost grows with how far into the file the reader is, so a short test near the start never shows it. On an ESP32-P4 a 29%-self-referenced image did not finish in 47 minutes until the benchmark built a map (070341a). The BL616 bridge an integration copies never had that fix, and its FatFs is built with FF_USE_FASTSEEK on. chd_fatfs_open() now builds the map right after f_open, before chd_open, so the header and map reads benefit too. The table is two words per fragment plus one; it starts at 16 words, grows to exactly what FatFs reports it needs, and past CHD_FATFS_CLMT_MAX runs without a map rather than failing - slower backward seeks, still correct. Compiled out entirely when FF_USE_FASTSEEK is 0. The close callback frees the table. libchdr calls it on a failed open too (#195), so the bridge's error path has nothing left to close. The RP2350 benchmark builds the same map, behind BENCH_LINKMAP so it can be measured on and off. Not measured yet on either board. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01846EhHuAFk5qvxwEA5Gq6y
cf60b8b to
9fcd4bc
Compare
|
Tested this on real BL616 hardware (Sipeed Tang Console 60K, TangCore firmware) and it Symptom
DE2 opened cleanly on every build before this change. Bisectlibchdr
So the cluster link map is the cause. Why it looks like wrong seeksA decompression error at open means the huffman-compressed v5 hunk map decoded from the Environment, since it is probably fragmentation-dependent
What I could not determineI read the builder and FatFs's side carefully and could not fault the logic:
So this is an empirical result, not a diagnosis. Two things I would look at first:
Happy to run more instrumented builds on this hardware if it would help — I can log |
Without a cluster link map, every backward
f_lseekwalks the FAT chain again from the file's first cluster — and everyCOMPRESSION_SELFhunk is a backward seek, to an earlier hunk the image references instead of storing twice. The cost grows with how far into the file the reader is, so a short test near the start never shows it.On an ESP32-P4 a 29%-self-referenced image did not finish in 47 minutes until the benchmark built a map (
070341a). The BL616 bridge that an integration copies never got that fix, and TangCore's FatFs is built withFF_USE_FASTSEEK 1— the capability is there, nothing was using it.What changes
chd_fatfs_open()builds the map right afterf_open, beforechd_open, so the header and map reads benefit too. The table needs two words per fragment plus one: it starts at 16 words, grows to exactly what FatFs reports it needs, and pastCHD_FATFS_CLMT_MAXruns without a map rather than failing — slower backward seeks, still correct. Compiled out whenFF_USE_FASTSEEKis 0.The close callback frees the table. Since #195, libchdr calls it on a failed open too, so the bridge's error path has nothing left to close.
The RP2350 benchmark builds the same map behind
BENCH_LINKMAP, so it can be measured with and without.Checked
bouffalo_sdk/components/fs/fatfs, R0.15) withFF_USE_FASTSEEKat 1 and at 0.f_lseekcall sites with it on.Not yet
Not measured on either board. The measurement that matters is a whole file with a high self-reference rate, map on and off — not a capped run, which is exactly what hid this on the P4.
🤖 Generated with Claude Code