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
+24 -24
View File
@@ -3665,8 +3665,8 @@ code = '''
uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
memset(seen, 0, (BLOCK_COUNT+7)/8);
lfs3_trv_t trv;
lfs3_trv_init(&trv,
lfs3_mtrv_t mtrv;
lfs3_mtrv_init(&mtrv,
LFS3_T_RDONLY
| LFS3_T_MTREEONLY
| ((CKMETA) ? LFS3_T_CKMETA : 0));
@@ -3676,7 +3676,7 @@ code = '''
lfs3_stag_t tag;
lfs3_bptr_t bptr;
tag = lfs3_mtree_traverse(&lfs3, &trv,
tag = lfs3_mtree_traverse(&lfs3, &mtrv,
&bptr);
assert(tag >= 0 || tag == LFS3_ERR_NOENT);
if (tag == LFS3_ERR_NOENT) {
@@ -3787,8 +3787,8 @@ code = '''
uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
memset(seen, 0, (BLOCK_COUNT+7)/8);
lfs3_trv_t trv;
lfs3_trv_init(&trv,
lfs3_mtrv_t mtrv;
lfs3_mtrv_init(&mtrv,
LFS3_T_RDONLY
| LFS3_T_MTREEONLY
| ((CKMETA) ? LFS3_T_CKMETA : 0));
@@ -3798,7 +3798,7 @@ code = '''
lfs3_stag_t tag;
lfs3_bptr_t bptr;
tag = lfs3_mtree_traverse(&lfs3, &trv,
tag = lfs3_mtree_traverse(&lfs3, &mtrv,
&bptr);
assert(tag >= 0 || tag == LFS3_ERR_NOENT);
if (tag == LFS3_ERR_NOENT) {
@@ -3935,8 +3935,8 @@ code = '''
uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
memset(seen, 0, (BLOCK_COUNT+7)/8);
lfs3_trv_t trv;
lfs3_trv_init(&trv,
lfs3_mtrv_t mtrv;
lfs3_mtrv_init(&mtrv,
LFS3_T_RDONLY
| LFS3_T_MTREEONLY
| ((CKMETA) ? LFS3_T_CKMETA : 0));
@@ -3946,7 +3946,7 @@ code = '''
lfs3_stag_t tag;
lfs3_bptr_t bptr;
tag = lfs3_mtree_traverse(&lfs3, &trv,
tag = lfs3_mtree_traverse(&lfs3, &mtrv,
&bptr);
assert(tag >= 0 || tag == LFS3_ERR_NOENT);
if (tag == LFS3_ERR_NOENT) {
@@ -4106,8 +4106,8 @@ code = '''
uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
memset(seen, 0, (BLOCK_COUNT+7)/8);
lfs3_trv_t trv;
lfs3_trv_init(&trv,
lfs3_mtrv_t mtrv;
lfs3_mtrv_init(&mtrv,
LFS3_T_RDONLY
| LFS3_T_MTREEONLY
| ((CKMETA) ? LFS3_T_CKMETA : 0));
@@ -4117,7 +4117,7 @@ code = '''
lfs3_stag_t tag;
lfs3_bptr_t bptr;
tag = lfs3_mtree_traverse(&lfs3, &trv,
tag = lfs3_mtree_traverse(&lfs3, &mtrv,
&bptr);
assert(tag >= 0 || tag == LFS3_ERR_NOENT);
if (tag == LFS3_ERR_NOENT) {
@@ -4257,8 +4257,8 @@ code = '''
uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
memset(seen, 0, (BLOCK_COUNT+7)/8);
lfs3_trv_t trv;
lfs3_trv_init(&trv,
lfs3_mtrv_t mtrv;
lfs3_mtrv_init(&mtrv,
LFS3_T_RDONLY
| LFS3_T_MTREEONLY
| ((CKMETA) ? LFS3_T_CKMETA : 0));
@@ -4268,7 +4268,7 @@ code = '''
lfs3_stag_t tag;
lfs3_bptr_t bptr;
tag = lfs3_mtree_traverse(&lfs3, &trv,
tag = lfs3_mtree_traverse(&lfs3, &mtrv,
&bptr);
assert(tag >= 0 || tag == LFS3_ERR_NOENT);
if (tag == LFS3_ERR_NOENT) {
@@ -4383,8 +4383,8 @@ code = '''
uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
memset(seen, 0, (BLOCK_COUNT+7)/8);
lfs3_trv_t trv;
lfs3_trv_init(&trv,
lfs3_mtrv_t mtrv;
lfs3_mtrv_init(&mtrv,
LFS3_T_RDONLY
| LFS3_T_MTREEONLY
| ((CKMETA) ? LFS3_T_CKMETA : 0));
@@ -4394,7 +4394,7 @@ code = '''
lfs3_stag_t tag;
lfs3_bptr_t bptr;
tag = lfs3_mtree_traverse(&lfs3, &trv,
tag = lfs3_mtree_traverse(&lfs3, &mtrv,
&bptr);
assert(tag >= 0 || tag == LFS3_ERR_NOENT);
if (tag == LFS3_ERR_NOENT) {
@@ -4553,8 +4553,8 @@ code = '''
uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
memset(seen, 0, (BLOCK_COUNT+7)/8);
lfs3_trv_t trv;
lfs3_trv_init(&trv,
lfs3_mtrv_t mtrv;
lfs3_mtrv_init(&mtrv,
LFS3_T_RDONLY
| LFS3_T_MTREEONLY
| ((CKMETA) ? LFS3_T_CKMETA : 0));
@@ -4564,7 +4564,7 @@ code = '''
lfs3_stag_t tag;
lfs3_bptr_t bptr;
tag = lfs3_mtree_traverse(&lfs3, &trv,
tag = lfs3_mtree_traverse(&lfs3, &mtrv,
&bptr);
assert(tag >= 0 || tag == LFS3_ERR_NOENT);
if (tag == LFS3_ERR_NOENT) {
@@ -4686,8 +4686,8 @@ code = '''
LFS3_MPTR_MROOTANCHOR()))) => 0;
// technically, cycle detection only needs to work when we're validating
lfs3_trv_t trv;
lfs3_trv_init(&trv,
lfs3_mtrv_t mtrv;
lfs3_mtrv_init(&mtrv,
LFS3_T_RDONLY | LFS3_T_MTREEONLY | LFS3_T_CKMETA);
for (lfs3_block_t i = 0;; i++) {
// assert that we detect the cycle in a reasonable number of iterations
@@ -4695,7 +4695,7 @@ code = '''
lfs3_stag_t tag;
lfs3_bptr_t bptr;
tag = lfs3_mtree_traverse(&lfs3, &trv,
tag = lfs3_mtree_traverse(&lfs3, &mtrv,
&bptr);
assert(tag >= 0 || tag == LFS3_ERR_CORRUPT);
if (tag == LFS3_ERR_CORRUPT) {