tweedegolf / tweedegolf/sequential-storage

store_item can acknowledge an item that disappears after reboot

Open
#136 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug disk-breaking
Dominant language
Rust
Stars
189
Forks
35
PR merge metrics
No merged PRs in 30d

Description

Summary

After two interrupted initial stores, a later uninterrupted MapStorage::store_item can return Ok(()), but a freshly reconstructed MapStorage cannot fetch the item and returns None.

I reproduced this directly on master at d10f0d517926c9b2303a1375f0da653443dec56a with the crate's own MockFlashBase; no external adapter is involved.

Minimal sequence

The flash geometry is two 128-byte pages with one-byte words, an uncached MapStorage<u8, ...>, key 0, and an eight-byte value.

  1. Set bytes_until_shutoff = Some(7) and attempt the initial store. It returns EarlyShutoff.
  2. Destroy and reconstruct MapStorage; fetching key 0 returns None.
  3. Repeat steps 1–2 once.
  4. Restore power and store a different value. store_item returns Ok(()).
  5. Destroy and reconstruct MapStorage again.
  6. Fetching key 0 returns None, despite the successful clean store.

Cause

ItemHeaderIter advances one flash word when it encounters a corrupted/torn header. find_next_free_item_spot then appends at the first erased byte following that header. Bytes from the new header can complete a valid-looking phantom header that starts inside the torn header and overlaps the new item. Traversal follows the phantom record and skips the actual item.

Expected behavior

An uninterrupted store_item that returns Ok(()) must remain visible after reconstructing the storage. If the flash state cannot be recovered safely, the store should return an error instead of acknowledging a non-durable item.

The regression test, a fix that rotates away from a page when the append scan encountered a corrupted header, and a new repeated power-cut/reboot fuzz target are submitted in #137.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the regression sequence using the crate's MockFlashBase, then read ItemHeaderIter and find_next_free_item_spot to trace how torn headers affect append scanning. Compare the proposed work in #137; done means a successful uninterrupted store remains fetchable after reconstruction, with coverage for repeated power cuts and reboots.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
embedded-iot
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.