Limited graft traversal scope to lfs3_alloc
This drops the LFS3_TSTATE_GRAFT state for just explicitly iterating
over graft state in lfs3_alloc. This is cheaper as long as lfs3_alloc is
the only traversal we trigger while grafting.
We already rely on the lfs3_alloc-specific behavior of never touching
cksize/cksum fields anyways.
Note both lfs3_alloc_markinuse and lfs3_alloc_markinuse_ already have
multiple call sites and can't be inlined due to lookahead population in
lfs3_mtree_gc. We also don't need to worry about graft state there as
incremental traversals only make progress when bshrubs are at rest.
Saves a bit of code:
code stack ctx
before: 38092 2456 656
after: 38060 (-0.1%) 2456 (+0.0%) 656 (+0.0%)
before graft: 37936 2456 636
after graft: 38060 (+0.3%) 2456 (+0.0%) 656 (+3.1%)
Actually, surprisingly little code, but anything that simplifies
lfs3_mtree_traverse_ is welcome.
This commit is contained in:
@@ -9722,9 +9722,8 @@ enum {
|
||||
LFS3_TSTATE_BTREE = 5,
|
||||
LFS3_TSTATE_OMDIRS = 6,
|
||||
LFS3_TSTATE_OBTREE = 7,
|
||||
LFS3_TSTATE_GRAFT = 8,
|
||||
#endif
|
||||
LFS3_TSTATE_DONE = 9,
|
||||
LFS3_TSTATE_DONE = 8,
|
||||
};
|
||||
|
||||
static void lfs3_traversal_init(lfs3_traversal_t *t, uint32_t flags) {
|
||||
@@ -9744,9 +9743,6 @@ static void lfs3_traversal_init(lfs3_traversal_t *t, uint32_t flags) {
|
||||
t->gcksum = 0;
|
||||
}
|
||||
|
||||
// needed in lfs3_mtree_traverse_
|
||||
static inline lfs3_size_t lfs3_graft_count(lfs3_size_t graft_count);
|
||||
|
||||
// low-level traversal _only_ finds blocks
|
||||
static int lfs3_mtree_traverse_(lfs3_t *lfs3, lfs3_traversal_t *t,
|
||||
lfs3_tag_t *tag_, lfs3_bptr_t *bptr) {
|
||||
@@ -9861,10 +9857,9 @@ static int lfs3_mtree_traverse_(lfs3_t *lfs3, lfs3_traversal_t *t,
|
||||
err = lfs3_mtree_lookup(lfs3, t->b.o.mdir.mid,
|
||||
&t->b.o.mdir);
|
||||
if (err) {
|
||||
// end of mtree? all that's left is any graft state
|
||||
// end of mtree? guess we're done
|
||||
if (err == LFS3_ERR_NOENT) {
|
||||
t->u.gt = 0;
|
||||
lfs3_t_settstate(&t->b.o.flags, LFS3_TSTATE_GRAFT);
|
||||
lfs3_t_settstate(&t->b.o.flags, LFS3_TSTATE_DONE);
|
||||
continue;
|
||||
}
|
||||
return err;
|
||||
@@ -10030,21 +10025,6 @@ static int lfs3_mtree_traverse_(lfs3_t *lfs3, lfs3_traversal_t *t,
|
||||
continue;
|
||||
#endif
|
||||
|
||||
// traverse through in-flight grafts
|
||||
case LFS3_TSTATE_GRAFT:;
|
||||
// done?
|
||||
if (t->u.gt >= lfs3_graft_count(lfs3->graft_count)) {
|
||||
lfs3_t_settstate(&t->b.o.flags, LFS3_TSTATE_DONE);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tag_) {
|
||||
*tag_ = LFS3_TAG_DATA;
|
||||
}
|
||||
bptr->data = lfs3->graft[t->u.gt];
|
||||
t->u.gt += 1;
|
||||
return 0;
|
||||
|
||||
case LFS3_TSTATE_DONE:;
|
||||
return LFS3_ERR_NOENT;
|
||||
|
||||
@@ -10382,8 +10362,7 @@ static void lfs3_alloc_markinuse(lfs3_t *lfs3,
|
||||
lfs3_rbyd_t *rbyd = (lfs3_rbyd_t*)bptr->data.u.buffer;
|
||||
lfs3_alloc_markinuse_(lfs3, rbyd->blocks[0]);
|
||||
|
||||
} else if (tag == LFS3_TAG_BLOCK
|
||||
|| tag == LFS3_TAG_DATA) {
|
||||
} else if (tag == LFS3_TAG_BLOCK) {
|
||||
lfs3_alloc_markinuse_(lfs3, lfs3_bptr_block(bptr));
|
||||
|
||||
} else {
|
||||
@@ -10458,6 +10437,9 @@ static lfs3_sblock_t lfs3_alloc_findfree(lfs3_t *lfs3) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// needed in lfs3_mtree_traverse_
|
||||
static inline lfs3_size_t lfs3_graft_count(lfs3_size_t graft_count);
|
||||
|
||||
#if !defined(LFS3_RDONLY) && !defined(LFS3_2BONLY)
|
||||
static lfs3_sblock_t lfs3_alloc(lfs3_t *lfs3, bool erase) {
|
||||
while (true) {
|
||||
@@ -10539,6 +10521,13 @@ static lfs3_sblock_t lfs3_alloc(lfs3_t *lfs3, bool erase) {
|
||||
lfs3_alloc_markinuse(lfs3, tag, &bptr);
|
||||
}
|
||||
|
||||
// mask out any in-flight graft state
|
||||
for (lfs3_size_t i = 0;
|
||||
i < lfs3_graft_count(lfs3->graft_count);
|
||||
i++) {
|
||||
lfs3_alloc_markinuse_(lfs3, lfs3->graft[i].u.disk.block);
|
||||
}
|
||||
|
||||
// mark anything not seen as free
|
||||
lfs3_alloc_markfree(lfs3);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user