Skip to content

FileStore: close the active segment before threshold compaction - #11

Open
genemichael wants to merge 1 commit into
attermann:masterfrom
genemichael:fix/compact-close-active-segment
Open

genemichael wants to merge 1 commit into
attermann:masterfrom
genemichael:fix/compact-close-active-segment

Conversation

@genemichael

Copy link
Copy Markdown

Summary

compact_if_threshold() calls compact() while active_file is still open. The rotation path (rotate_segment_if_needed()) closes the active file before compacting, but the threshold path does not.

On ESP-IDF LittleFS, unlinking an open file is refused, so every threshold-triggered compaction fails to delete the active segment and logs:

E esp_littlefs: Failed to unlink path "./hashlist_store/seg1.dat". Has open FD.

twice per compaction (once in compact()'s per-segment delete, once in finalize_compaction()). Plain POSIX permits unlinking an open file, which is why this doesn't reproduce off-device.

Change

In compact_if_threshold(): flush_buffer(), close active_file, then compact(). On success open seg1 as before; on failure or skip, reopen current_segment so appends continue. Ten lines, mirrors the existing rotation path.

Where it was seen

microReticulum_Firmware on a Heltec WiFi LoRa 32 V4 relaying link traffic between LoRa and a TCP interface. microReticulum's packet hashlist store defaults to 100 records, so with the 25% dead-record threshold the store compacts every ~25 forwarded packets, and each one hit this. Verified the error stops with the patch applied to the PlatformIO libdeps copy.

🤖 Generated with Claude Code

compact_if_threshold() called compact() with active_file still open.
rotate_segment_if_needed() closes it first, but the threshold path did not,
so on ESP-IDF LittleFS every threshold-triggered compaction failed to delete
the active segment:

  E esp_littlefs: Failed to unlink path "./hashlist_store/seg1.dat". Has open FD.

Plain POSIX allows unlinking an open file, which is why this never showed up
off-device. Flush and close active_file before compact(), and reopen the
current segment if compaction fails or is skipped so appends continue.

Seen on microReticulum_Firmware (Heltec V4) relaying link traffic, where the
100-record packet hashlist hits the 25% dead threshold every ~25 packets.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant