Files
littlefs/tests
Christopher Haster 488e84bb53 Fixed data corruption with multiple write handles
Multiple write handles in littlefs has always been a bit confusing
(hopefully improving in littlefs3), but I didn't realize it could lead
to corrupted data.

The problem, as noted by Ictogan1, is that syncs to related file handles
ignores the LFS_F_DIRTY flag. If you open a file twice, and write to one
handle, littlefs doesn't realize the other handle it out-of-date.

This may not seem like a problem, but then littlefs is happy to
reallocate those (still referenced) blocks, leading to data corruption:

  open(a, "quiche.txt")
  write(a)
  sync(a) // syncs a's contents
  open(b, "quiche.txt")
  truncate(b)
  sync(b) // syncs b's contents
  write(b) // may allocate from a
  rewind(a)
  read(a) // potentially corrupted

---

What we want is to set LFS_F_DIRTY in all other file handles during
lfs_file_sync, but doing so would force those file handles to sync
during close. That would be even more confusing (not to mention
backwards incompatible).

In theory setting both LFS_F_DIRTY + LFS_F_ERRED could work, but that
would prevent implicit syncs of writes that haven't actually errored:

  open(a, "quiche.txt")
  write(a)
  open(b, "quiche.txt")
  write(b)
  close(b) // syncs b's contents
  close(a) // should sync a's contents

So, instead, as a somewhat clunky workaround, a new flag: LFS_F_DUSTY,
which indicates a file does not match storage, but should not be synced
during close.

---

It's worth noting this is already fixed in littlefs3, which includes a
more rigorous, and hopefully easier to use sync model. But in the
meantime, this should at least prevent the loss of data.

Added test_alloc_multihandle and test_alloc_multihandle_reuse to prevent
a regression, test_alloc_multihandle_reuse does reproduce the bug.

Found and reproduced by Ictogan1
2026-03-09 19:13:43 -05:00
..