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%)
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user