From 624eb1ad52be9ab4fe1d378ed062aefa5596dcd5 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Thu, 16 Jan 2025 14:53:13 -0600 Subject: [PATCH] Fixed gcksum mismatch in dirty/mutated traversal It's an error to check the gcksum if our traversal ends up dirty/mutated, since it may be contain cksums from different filesystem states. We already avoid clearing the CKMETA flag if this happens, so no change needed there. lfsr_fs_gc will continue to traverse until this flag is cleared. (Though running a ckmeta scan to completion before any mutation _would_ be more robust, hmm...) Found by our test_traversal_mutation test. Code changes were zero after tweaking lfsr_mtree_traverse to better deduplicate ckmeta/ckdata eot conditions: code stack ctx before: 38572 2640 644 after: 38572 (+0.0%) 2640 (+0.0%) 644 (+0.0%) --- lfs.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lfs.c b/lfs.c index 69ce03b8..7a70818d 100644 --- a/lfs.c +++ b/lfs.c @@ -9631,6 +9631,8 @@ eot:; // compare gcksum with in-RAM gcksum if ((lfsr_t_isckmeta(t->o.o.flags) || lfsr_t_isckdata(t->o.o.flags)) + && !lfsr_t_isdirty(t->o.o.flags) + && !lfsr_t_ismutated(t->o.o.flags) && t->gcksum != lfs->gcksum) { LFS_ERROR("Found gcksum mismatch, cksum %08"PRIx32" (!= %08"PRIx32")", t->gcksum, @@ -9640,7 +9642,8 @@ eot:; // was ckmeta/ckdata successful? we only consider our filesystem // checked if we weren't mutated - if (lfsr_t_isckmeta(t->o.o.flags) + if ((lfsr_t_isckmeta(t->o.o.flags) + || lfsr_t_isckdata(t->o.o.flags)) && !lfsr_t_ismtreeonly(t->o.o.flags) && !lfsr_t_isdirty(t->o.o.flags) && !lfsr_t_ismutated(t->o.o.flags)) { @@ -9650,8 +9653,7 @@ eot:; && !lfsr_t_ismtreeonly(t->o.o.flags) && !lfsr_t_isdirty(t->o.o.flags) && !lfsr_t_ismutated(t->o.o.flags)) { - // note ckdata implies ckmeta - lfs->flags &= ~LFS_I_CKDATA & ~LFS_I_CKMETA; + lfs->flags &= ~LFS_I_CKDATA; } return LFS_ERR_NOENT;