From 88eb1714b13d9ee758d875f31c7fb5d89a3339da Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Thu, 5 Jun 2025 15:01:25 -0500 Subject: [PATCH] t: Fixed exceptional traversal errors mixing up dirty/mutated flags This function is kinda ugly in that our failed label expects the dirty/mutated flags to be swapped, but we only swap _after_ calling lfs3_mtree_traverse to avoid messing up lfs3_mtree_traverse's eot logic. Long story short, this goto failed after lfs3_mtree_traverse could end up with drity/mutated in the wrong state. Worst case, this can leave littlefs in a state where it thinks work was accomplished, but only if lfs3_mtree_traverse encounters an exceptional error (LFS3_ERR_IO? LFS3_ERR_CORRUPT?), which usually leads to emergency actions anyways. We probably need more testing around exceptional errors like these, they're also the main limit to our line/branch coverage. But the work will be tedious so for now that's a future thing. I at least added a comment to hopefully prevent a similar regression. Code changes minimal, humorously undoes the LFS3_RDONLY noise: code stack ctx before: 37304 2280 636 after: 37300 (-0.0%) 2280 (+0.0%) 636 (+0.0%) --- lfs3.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lfs3.c b/lfs3.c index f9a5181e..7ec6cb0c 100644 --- a/lfs3.c +++ b/lfs3.c @@ -9927,7 +9927,9 @@ dropped:; if (err == LFS3_ERR_NOENT) { goto eot; } - goto failed; + // don't goto failed here, we haven't swapped dirty/mutated + // flags yet + return err; } #ifndef LFS3_RDONLY @@ -9999,6 +10001,13 @@ dropped:; } return 0; + #ifndef LFS3_RDONLY +failed:; + // swap back dirty/mutated flags + t->b.o.flags = lfs3_t_swapdirty(t->b.o.flags); + return err; + #endif + eot:; #ifndef LFS3_RDONLY // was lookahead scan successful? @@ -10025,13 +10034,6 @@ eot:; #endif return LFS3_ERR_NOENT; - - #ifndef LFS3_RDONLY -failed:; - // swap back dirty/mutated flags - t->b.o.flags = lfs3_t_swapdirty(t->b.o.flags); - return err; - #endif }