From 360170f0f42b1f37213ae3086a3fc0f450d63425 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sat, 6 Dec 2025 13:20:53 -0600 Subject: [PATCH] trv: Deduplicated mgc related lfs3_fs_fixgrm calls If lfs3_fs_fixgrm is an implicit requirement for LFS3_T_MKCONSISTENT, we might as well move it into the core lfs3_mtree_gc logic and save on the redundant lfs3_fs_fixgrm calls. Saves a bit of code: code stack ctx before: 35164 2136 660 after: 35128 (-0.1%) 2136 (+0.0%) 660 (+0.0%) code stack ctx gbmap before: 38088 2136 776 gbmap after: 38052 (-0.1%) 2136 (+0.0%) 776 (+0.0%) --- lfs3.c | 75 ++++++++++++++++++++-------------------------------------- 1 file changed, 25 insertions(+), 50 deletions(-) diff --git a/lfs3.c b/lfs3.c index 62229c6d..eb6f950a 100644 --- a/lfs3.c +++ b/lfs3.c @@ -10248,6 +10248,7 @@ eot:; } // needed in lfs3_mtree_gc +static int lfs3_fs_fixgrm(lfs3_t *lfs3); static int lfs3_mdir_mkconsistent(lfs3_t *lfs3, lfs3_mdir_t *mdir); static inline void lfs3_alloc_ckpoint_(lfs3_t *lfs3); static inline bool lfs3_alloc_canlookahead(const lfs3_t *lfs3); @@ -10264,6 +10265,22 @@ static int lfs3_alloc_adoptgbmap(lfs3_t *lfs3, // mutation here static lfs3_stag_t lfs3_mtree_gc(lfs3_t *lfs3, lfs3_mgc_t *mgc, lfs3_bptr_t *bptr_) { + // check for pending grms every step, just in case some other + // operation introduced new grms + #ifndef LFS3_RDONLY + if (lfs3_t_ismkconsistent(mgc->t.h.flags) + && lfs3_grm_count(lfs3) > 0) { + // fix pending grms + uint32_t dirty = mgc->t.h.flags; + int err = lfs3_fs_fixgrm(lfs3); + if (err) { + return err; + } + // reset dirty flag + mgc->t.h.flags &= ~LFS3_t_DIRTY | dirty; + } + #endif + // start of traversal? if (mgc->t.h.mdir.mid == LFS3_MID_MROOTANCHOR) { #ifndef LFS3_RDONLY @@ -11447,9 +11464,6 @@ empty:; } #endif -// needed in lfs3_remove -static int lfs3_fs_fixgrm(lfs3_t *lfs3); - #ifndef LFS3_RDONLY int lfs3_remove(lfs3_t *lfs3, const char *path) { // prepare our filesystem for writing @@ -16300,9 +16314,15 @@ failed:; } #endif +// prepare the filesystem for mutation #ifndef LFS3_RDONLY -static int lfs3_fs_fixorphans(lfs3_t *lfs3) { - // LFS3_T_MKCONSISTENT really just removes orphans +int lfs3_fs_mkconsistent(lfs3_t *lfs3) { + // filesystem must be writeable + LFS3_ASSERT(!lfs3_m_isrdonly(lfs3->flags)); + + // LFS3_T_MKCONSISTENT does most of the work: + // 1. fixes pending grms + // 2. fixes orphaned stickynotes lfs3_mgc_t mgc; lfs3_mgc_init(&mgc, LFS3_T_RDWR | LFS3_T_MTREEONLY | LFS3_T_MKCONSISTENT); @@ -16318,36 +16338,6 @@ static int lfs3_fs_fixorphans(lfs3_t *lfs3) { } } - return 0; -} -#endif - -// prepare the filesystem for mutation -#ifndef LFS3_RDONLY -int lfs3_fs_mkconsistent(lfs3_t *lfs3) { - // filesystem must be writeable - LFS3_ASSERT(!lfs3_m_isrdonly(lfs3->flags)); - - // fix pending grms - if (lfs3_grm_count(lfs3) > 0) { - int err = lfs3_fs_fixgrm(lfs3); - if (err) { - return err; - } - } - - // fix orphaned stickynotes - // - // this must happen after fixgrm, since removing orphaned - // stickynotes risks outdating the grm - // - if (lfs3_t_ismkconsistent(lfs3->flags)) { - int err = lfs3_fs_fixorphans(lfs3); - if (err) { - return err; - } - } - // go ahead and checkpoint the allocator // // this isn't always needed, but redundant alloc ckpoints are noops, @@ -16812,21 +16802,6 @@ int lfs3_trv_read(lfs3_t *lfs3, lfs3_trv_t *trv, return LFS3_ERR_BUSY; } - // check for pending grms every step, just in case some other - // operation introduced new grms - #ifndef LFS3_RDONLY - if (lfs3_t_ismkconsistent(trv->gc.t.h.flags) - && lfs3_grm_count(lfs3) > 0) { - uint32_t dirty = trv->gc.t.h.flags; - int err = lfs3_fs_fixgrm(lfs3); - if (err) { - return err; - } - // reset dirty flag - trv->gc.t.h.flags &= ~LFS3_t_DIRTY | dirty; - } - #endif - // discard current block queue? if (lfs3_t_isstale(trv->gc.t.h.flags)) { trv->blocks[0] = -1;