trv: Split lfs3_trv_t -> lfs3_trv_t, lfs3_mgc_t, and lfs3_mtrv_t

A big downside of LFS3_T_REBUILDGBMAP is the addition of an lfs3_btree_t
struct to _every_ traversal object.

Unfortunately, I don't see a way around this. We need to track the new
gbmap snapshot _somewhere_, and other options (such as a global gbmap.b_
snapshot) just move the RAM around without actually saving anything.

To at least mitigate this internally, this splits lfs3_trv_t into
distinct lfs3_trv_t, lfs3_mgc_t, and lfs3_mtrv_t structs that capture
only the relevant state for internal traversal layers:

- lfs3_mtree_traverse <- lfs3_mtrv_t
- lfs3_mtree_gc       <- lfs3_mgc_t (contains lfs3_mtrv_t)
- lfs3_trv_read       <- lfs3_trv_t (contains lfs3_mgc_t)

This minimizes the impact of the gbmap rebuild snapshots, and saves a
big chunk of RAM. As a plus it also saves RAM in the default build by
limiting the 2-block block queue to the high-level lfs3_trv_read API:

                 code          stack          ctx
  before:       37176           2360          684
  after:        37176 (+0.0%)   2352 (-0.3%)  684 (+0.0%)

                 code          stack          ctx
  gbmap before: 40060           2432          848
  gbmap after:  40024 (-0.1%)   2368 (-2.6%)  848 (+0.0%)

The main downside? Our field names are continuing in their
ridiculousness:

  lfs3.gc.gc.t.b.h.flags // where else would the global gc flags be?
This commit is contained in:
Christopher Haster
2025-10-16 00:10:21 -05:00
parent 06bc4dff04
commit fb90bf976c
6 changed files with 299 additions and 285 deletions
+18 -8
View File
@@ -819,7 +819,7 @@ typedef struct lfs3_dir {
} lfs3_dir_t;
// littlefs traversal type
typedef struct lfs3_trv {
typedef struct lfs3_mtrv {
// mdir/bshrub/btree state, this also includes our traversal
// state machine and cycle detection state
lfs3_bshrub_t b;
@@ -828,12 +828,24 @@ typedef struct lfs3_trv {
// bshrub/btree traversal state
lfs3_sbid_t bid;
// rebuild gbmap when traversing with rebuildgbmap
#ifdef LFS3_GBMAP
lfs3_btree_t gbmap_;
#endif
// recalculate gcksum when traversing with ckmeta
uint32_t gcksum;
} lfs3_mtrv_t;
typedef struct lfs3_mgc {
// core traversal state
lfs3_mtrv_t t;
#ifdef LFS3_GBMAP
// rebuild gbmap when traversing with rebuildgbmap
lfs3_btree_t gbmap_;
#endif
} lfs3_mgc_t;
typedef struct lfs3_trv {
// core traversal/gc state
lfs3_mgc_t gc;
// pending blocks, only used in lfs3_trv_read
lfs3_sblock_t blocks[2];
} lfs3_trv_t;
@@ -962,9 +974,7 @@ typedef struct lfs3 {
// optional incremental gc state
#ifdef LFS3_GC
struct {
lfs3_trv_t trv;
} gc;
lfs3_trv_t gc;
#endif
} lfs3_t;