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_BTREE = 5,
|
||||||
LFS3_TSTATE_OMDIRS = 6,
|
LFS3_TSTATE_OMDIRS = 6,
|
||||||
LFS3_TSTATE_OBTREE = 7,
|
LFS3_TSTATE_OBTREE = 7,
|
||||||
LFS3_TSTATE_GRAFT = 8,
|
|
||||||
#endif
|
#endif
|
||||||
LFS3_TSTATE_DONE = 9,
|
LFS3_TSTATE_DONE = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void lfs3_traversal_init(lfs3_traversal_t *t, uint32_t flags) {
|
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;
|
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
|
// low-level traversal _only_ finds blocks
|
||||||
static int lfs3_mtree_traverse_(lfs3_t *lfs3, lfs3_traversal_t *t,
|
static int lfs3_mtree_traverse_(lfs3_t *lfs3, lfs3_traversal_t *t,
|
||||||
lfs3_tag_t *tag_, lfs3_bptr_t *bptr) {
|
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,
|
err = lfs3_mtree_lookup(lfs3, t->b.o.mdir.mid,
|
||||||
&t->b.o.mdir);
|
&t->b.o.mdir);
|
||||||
if (err) {
|
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) {
|
if (err == LFS3_ERR_NOENT) {
|
||||||
t->u.gt = 0;
|
lfs3_t_settstate(&t->b.o.flags, LFS3_TSTATE_DONE);
|
||||||
lfs3_t_settstate(&t->b.o.flags, LFS3_TSTATE_GRAFT);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
@@ -10030,21 +10025,6 @@ static int lfs3_mtree_traverse_(lfs3_t *lfs3, lfs3_traversal_t *t,
|
|||||||
continue;
|
continue;
|
||||||
#endif
|
#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:;
|
case LFS3_TSTATE_DONE:;
|
||||||
return LFS3_ERR_NOENT;
|
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_rbyd_t *rbyd = (lfs3_rbyd_t*)bptr->data.u.buffer;
|
||||||
lfs3_alloc_markinuse_(lfs3, rbyd->blocks[0]);
|
lfs3_alloc_markinuse_(lfs3, rbyd->blocks[0]);
|
||||||
|
|
||||||
} else if (tag == LFS3_TAG_BLOCK
|
} else if (tag == LFS3_TAG_BLOCK) {
|
||||||
|| tag == LFS3_TAG_DATA) {
|
|
||||||
lfs3_alloc_markinuse_(lfs3, lfs3_bptr_block(bptr));
|
lfs3_alloc_markinuse_(lfs3, lfs3_bptr_block(bptr));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -10458,6 +10437,9 @@ static lfs3_sblock_t lfs3_alloc_findfree(lfs3_t *lfs3) {
|
|||||||
}
|
}
|
||||||
#endif
|
#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)
|
#if !defined(LFS3_RDONLY) && !defined(LFS3_2BONLY)
|
||||||
static lfs3_sblock_t lfs3_alloc(lfs3_t *lfs3, bool erase) {
|
static lfs3_sblock_t lfs3_alloc(lfs3_t *lfs3, bool erase) {
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -10539,6 +10521,13 @@ static lfs3_sblock_t lfs3_alloc(lfs3_t *lfs3, bool erase) {
|
|||||||
lfs3_alloc_markinuse(lfs3, tag, &bptr);
|
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
|
// mark anything not seen as free
|
||||||
lfs3_alloc_markfree(lfs3);
|
lfs3_alloc_markfree(lfs3);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user