From 1dc1a26f11fa78bee0d9cff4a7a726c060ec9962 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Thu, 16 Oct 2025 16:20:07 -0500 Subject: [PATCH] gc: Added LFS3_GC_ALL to make running all gc work easier This is an alias for all possible gc work, which is a bit more complicated than you might think due to compile-time features (example: LFS3_GC_REPOPGBMAP). The intention is to make loops like the following easy to write: struct lfs3_fsinfo fsinfo; lfs3_fs_stat(&lfs3, &fsinfo) => 0; lfs3_trv_t trv; lfs3_trv_open(&lfs3, &trv, fsinfo.flags & LFS3_GC_ALL) => 0; ... It's possible to do this by explicitly setting all gc flags, but that requires quite a bit of knowledge from the user. Another option is allowing -1 for gc/traversal flags, but that loses assert protection against unknown/misplaced flags. --- This raises more questions about the prefix naming: it feels a bit weird to take LFS3_I_* flags, mask with LFS3_GC_* flags, and pass them as LFS3_T_* flags, but it gets the job done. Limiting LFS3_GC_ALL to the LFS3_GC_* namespace avoids issues with opt-out/mode flags such as LFS3_T_RDONLY, LFS3_T_MTREEONLY, etc. For this reason it probably doesn't make sense to add something similar to the other namespaces. --- lfs3.c | 61 ++++++++++-------------------------------- lfs3.h | 10 +++++++ runners/bench_runner.h | 2 +- runners/test_runner.h | 2 +- 4 files changed, 26 insertions(+), 49 deletions(-) diff --git a/lfs3.c b/lfs3.c index 7bcf3d63..4726d4ec 100644 --- a/lfs3.c +++ b/lfs3.c @@ -17027,27 +17027,16 @@ int lfs3_fs_cksum(lfs3_t *lfs3, uint32_t *cksum) { static int lfs3_fs_gc_(lfs3_t *lfs3, lfs3_mgc_t *mgc, uint32_t flags, lfs3_soff_t steps) { // unknown gc flags? - // - // we should have check these earlier, but it doesn't hurt to - // double check - LFS3_ASSERT((flags & ~( - LFS3_IFDEF_RDONLY(0, LFS3_T_MKCONSISTENT) - | LFS3_IFDEF_RDONLY(0, LFS3_T_REPOPLOOKAHEAD) - | LFS3_IFDEF_RDONLY(0, - LFS3_IFDEF_GBMAP(LFS3_T_REPOPGBMAP, 0)) - | LFS3_IFDEF_RDONLY(0, LFS3_T_COMPACTMETA) - | LFS3_T_CKMETA - | LFS3_T_CKDATA)) == 0); + LFS3_ASSERT((flags & ~LFS3_GC_ALL) == 0); // these flags require a writable filesystem - LFS3_ASSERT(!lfs3_m_isrdonly(lfs3->flags) || !lfs3_t_ismkconsistent(flags)); + LFS3_ASSERT(!lfs3_m_isrdonly(lfs3->flags) + || !lfs3_t_ismkconsistent(flags)); LFS3_ASSERT(!lfs3_m_isrdonly(lfs3->flags) || !lfs3_t_isrepoplookahead(flags)); - LFS3_ASSERT(!lfs3_m_isrdonly(lfs3->flags) || !lfs3_t_isrepopgbmap(flags)); - LFS3_ASSERT(!lfs3_m_isrdonly(lfs3->flags) || !lfs3_t_compactmeta(flags)); - // some flags don't make sense when only traversing the mtree - LFS3_ASSERT(!lfs3_t_ismtreeonly(flags) || !lfs3_t_isrepoplookahead(flags)); - LFS3_ASSERT(!lfs3_t_ismtreeonly(flags) || !lfs3_t_isrepopgbmap(flags)); - LFS3_ASSERT(!lfs3_t_ismtreeonly(flags) || !lfs3_t_isckdata(flags)); + LFS3_ASSERT(!lfs3_m_isrdonly(lfs3->flags) + || !lfs3_t_isrepopgbmap(flags)); + LFS3_ASSERT(!lfs3_m_isrdonly(lfs3->flags) + || !lfs3_t_compactmeta(flags)); // fix pending grms if requested #ifndef LFS3_RDONLY @@ -17061,15 +17050,7 @@ static int lfs3_fs_gc_(lfs3_t *lfs3, lfs3_mgc_t *mgc, #endif // do we have any pending work? - uint32_t pending = flags & ( - (lfs3->flags & ( - LFS3_IFDEF_RDONLY(0, LFS3_I_MKCONSISTENT) - | LFS3_IFDEF_RDONLY(0, LFS3_I_REPOPLOOKAHEAD) - | LFS3_IFDEF_RDONLY(0, - LFS3_IFDEF_GBMAP(LFS3_I_REPOPGBMAP, 0)) - | LFS3_IFDEF_RDONLY(0, LFS3_I_COMPACTMETA) - | LFS3_I_CKMETA - | LFS3_I_CKDATA))); + uint32_t pending = flags & (lfs3->flags & LFS3_GC_ALL); while (pending && (lfs3_off_t)steps > 0) { // start a new traversal? @@ -17089,25 +17070,18 @@ static int lfs3_fs_gc_(lfs3_t *lfs3, lfs3_mgc_t *mgc, #endif // will this traversal still make progress? no? start over - if (!(mgc->t.b.h.flags & ( - LFS3_IFDEF_RDONLY(0, LFS3_T_MKCONSISTENT) - | LFS3_IFDEF_RDONLY(0, LFS3_T_REPOPLOOKAHEAD) - | LFS3_IFDEF_RDONLY(0, - LFS3_IFDEF_GBMAP(LFS3_T_REPOPGBMAP, 0)) - | LFS3_IFDEF_RDONLY(0, LFS3_T_COMPACTMETA) - | LFS3_T_CKMETA - | LFS3_T_CKDATA))) { + if (!(mgc->t.b.h.flags & LFS3_GC_ALL)) { lfs3_handle_close(lfs3, &mgc->t.b.h); continue; } // do we really need a full traversal? if (!(mgc->t.b.h.flags & ( - LFS3_IFDEF_RDONLY(0, LFS3_T_REPOPLOOKAHEAD) + LFS3_IFDEF_RDONLY(0, LFS3_GC_REPOPLOOKAHEAD) | LFS3_IFDEF_RDONLY(0, - LFS3_IFDEF_GBMAP(LFS3_T_REPOPGBMAP, 0)) - | LFS3_T_CKMETA - | LFS3_T_CKDATA))) { + LFS3_IFDEF_GBMAP(LFS3_GC_REPOPGBMAP, 0)) + | LFS3_GC_CKMETA + | LFS3_GC_CKDATA))) { mgc->t.b.h.flags |= LFS3_T_MTREEONLY; } @@ -17124,14 +17098,7 @@ static int lfs3_fs_gc_(lfs3_t *lfs3, lfs3_mgc_t *mgc, lfs3_handle_close(lfs3, &mgc->t.b.h); // clear any pending flags we make progress on - pending &= lfs3->flags & ( - LFS3_IFDEF_RDONLY(0, LFS3_I_MKCONSISTENT) - | LFS3_IFDEF_RDONLY(0, LFS3_I_REPOPLOOKAHEAD) - | LFS3_IFDEF_RDONLY(0, - LFS3_IFDEF_GBMAP(LFS3_I_REPOPGBMAP, 0)) - | LFS3_IFDEF_RDONLY(0, LFS3_I_COMPACTMETA) - | LFS3_I_CKMETA - | LFS3_I_CKDATA); + pending &= lfs3->flags & LFS3_GC_ALL; } // decrement steps diff --git a/lfs3.h b/lfs3.h index 6a6c3224..8ab72a6a 100644 --- a/lfs3.h +++ b/lfs3.h @@ -369,6 +369,16 @@ enum lfs3_btype { #define LFS3_GC_CKMETA 0x00001000 // Check metadata checksums #define LFS3_GC_CKDATA 0x00002000 // Check metadata + data checksums +// an alias for all possible GC work +#define LFS3_GC_ALL ( \ + LFS3_IFDEF_RDONLY(0, LFS3_GC_MKCONSISTENT) \ + | LFS3_IFDEF_RDONLY(0, LFS3_GC_REPOPLOOKAHEAD) \ + | LFS3_IFDEF_RDONLY(0, \ + LFS3_IFDEF_GBMAP(LFS3_GC_REPOPGBMAP, 0)) \ + | LFS3_IFDEF_RDONLY(0, LFS3_GC_COMPACTMETA) \ + | LFS3_GC_CKMETA \ + | LFS3_GC_CKDATA) + // Configuration provided during initialization of the littlefs struct lfs3_cfg { diff --git a/runners/bench_runner.h b/runners/bench_runner.h index e46b2a3a..fbb2de77 100644 --- a/runners/bench_runner.h +++ b/runners/bench_runner.h @@ -114,7 +114,7 @@ void bench_permutation(size_t i, uint32_t *buffer, size_t size); BENCH_DEFINE(PCACHE_SIZE, LFS3_MAX(16, PROG_SIZE) ) \ BENCH_DEFINE(FILE_CACHE_SIZE, 16 ) \ BENCH_DEFINE(LOOKAHEAD_SIZE, 16 ) \ - BENCH_DEFINE(GC_FLAGS, 0 ) \ + BENCH_DEFINE(GC_FLAGS, LFS3_GC_ALL ) \ BENCH_DEFINE(GC_STEPS, 0 ) \ BENCH_DEFINE(GC_COMPACTMETA_THRESH, 0 ) \ BENCH_DEFINE(SHRUB_SIZE, BLOCK_SIZE/4 ) \ diff --git a/runners/test_runner.h b/runners/test_runner.h index 832cabc9..3c4ca35d 100644 --- a/runners/test_runner.h +++ b/runners/test_runner.h @@ -105,7 +105,7 @@ void test_permutation(size_t i, uint32_t *buffer, size_t size); TEST_DEFINE(PCACHE_SIZE, LFS3_MAX(16, PROG_SIZE) ) \ TEST_DEFINE(FILE_CACHE_SIZE, 16 ) \ TEST_DEFINE(LOOKAHEAD_SIZE, 16 ) \ - TEST_DEFINE(GC_FLAGS, 0 ) \ + TEST_DEFINE(GC_FLAGS, LFS3_GC_ALL ) \ TEST_DEFINE(GC_STEPS, 0 ) \ TEST_DEFINE(GC_COMPACTMETA_THRESH, 0 ) \ TEST_DEFINE(SHRUB_SIZE, BLOCK_SIZE/4 ) \