Added lfsr_data_fetchmdir
Like lfsr_data_fetchbtree/branch, lfsr_data_fetchmdir merges both the
data read/decode and fetch steps into a single function that should
hopefully result in better code deduplication.
Unlike lfsr_data_fetchbtree/branch, this is actually a net positive for
code savings. And because we can abuse the mptr in the yet-uninit mdir,
we can even shave off a bit of stack:
code stack
default before: 36456 2680
default after: 36436 (-0.1%) 2672 (-0.3%)
ckfetches before: 36686 2712
ckfetches after: 36674 (-0.0%) 2704 (-0.3%)
This commit is contained in:
@@ -7206,6 +7206,19 @@ static int lfsr_mdir_fetch(lfs_t *lfs, lfsr_mdir_t *mdir,
|
|||||||
return LFS_ERR_CORRUPT;
|
return LFS_ERR_CORRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int lfsr_data_fetchmdir(lfs_t *lfs,
|
||||||
|
lfsr_data_t *data, lfsr_smid_t mid,
|
||||||
|
lfsr_mdir_t *mdir) {
|
||||||
|
// decode mptr and fetch
|
||||||
|
int err = lfsr_data_readmptr(lfs, data,
|
||||||
|
(lfsr_mptr_t*)mdir->rbyd.blocks);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lfsr_mdir_fetch(lfs, mdir, mid, lfsr_mdir_mptr(mdir));
|
||||||
|
}
|
||||||
|
|
||||||
static int lfsr_mdir_lookupnext(lfs_t *lfs, const lfsr_mdir_t *mdir,
|
static int lfsr_mdir_lookupnext(lfs_t *lfs, const lfsr_mdir_t *mdir,
|
||||||
lfsr_tag_t tag,
|
lfsr_tag_t tag,
|
||||||
lfsr_tag_t *tag_, lfsr_data_t *data_) {
|
lfsr_tag_t *tag_, lfsr_data_t *data_) {
|
||||||
@@ -7386,15 +7399,9 @@ static int lfsr_mtree_lookup(lfs_t *lfs, lfsr_smid_t mid,
|
|||||||
LFS_ASSERT((lfsr_sbid_t)bid == lfsr_mid_bid(lfs, mid));
|
LFS_ASSERT((lfsr_sbid_t)bid == lfsr_mid_bid(lfs, mid));
|
||||||
LFS_ASSERT(tag == LFSR_TAG_MDIR);
|
LFS_ASSERT(tag == LFSR_TAG_MDIR);
|
||||||
|
|
||||||
// decode mdir
|
|
||||||
lfsr_mptr_t mptr;
|
|
||||||
err = lfsr_data_readmptr(lfs, &data, &mptr);
|
|
||||||
if (err) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fetch mdir
|
// fetch mdir
|
||||||
return lfsr_mdir_fetch(lfs, mdir_, mid, &mptr);
|
return lfsr_data_fetchmdir(lfs, &data, mid,
|
||||||
|
mdir_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8931,15 +8938,9 @@ static int lfsr_mtree_namelookup(lfs_t *lfs,
|
|||||||
LFS_ASSERT(tag == LFSR_TAG_MDIR);
|
LFS_ASSERT(tag == LFSR_TAG_MDIR);
|
||||||
LFS_ASSERT(weight == (1U << lfs->mdir_bits));
|
LFS_ASSERT(weight == (1U << lfs->mdir_bits));
|
||||||
|
|
||||||
// decode mdir
|
|
||||||
lfsr_mptr_t mptr;
|
|
||||||
int err = lfsr_data_readmptr(lfs, &data, &mptr);
|
|
||||||
if (err) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fetch mdir
|
// fetch mdir
|
||||||
err = lfsr_mdir_fetch(lfs, &mdir, bid-(weight-1), &mptr);
|
int err = lfsr_data_fetchmdir(lfs, &data, bid-(weight-1),
|
||||||
|
&mdir);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -9194,8 +9195,9 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t,
|
|||||||
|
|
||||||
// found a new mroot
|
// found a new mroot
|
||||||
if (tag == LFSR_TAG_MROOT) {
|
if (tag == LFSR_TAG_MROOT) {
|
||||||
lfsr_mptr_t mptr;
|
// fetch this mroot
|
||||||
err = lfsr_data_readmptr(lfs, &data, &mptr);
|
err = lfsr_data_fetchmdir(lfs, &data, -1,
|
||||||
|
&t->o.o.mdir);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -9206,26 +9208,22 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t,
|
|||||||
// btree inner nodes require checksums of their pointers,
|
// btree inner nodes require checksums of their pointers,
|
||||||
// so creating a valid cycle is actually quite difficult
|
// so creating a valid cycle is actually quite difficult
|
||||||
//
|
//
|
||||||
if (lfsr_mptr_cmp(&mptr, &t->u.mtortoise.mptr) == 0) {
|
if (lfsr_mptr_cmp(
|
||||||
|
lfsr_mdir_mptr(&t->o.o.mdir),
|
||||||
|
&t->u.mtortoise.mptr) == 0) {
|
||||||
LFS_ERROR("Cycle detected during mtree traversal "
|
LFS_ERROR("Cycle detected during mtree traversal "
|
||||||
"0x{%"PRIx32",%"PRIx32"}",
|
"0x{%"PRIx32",%"PRIx32"}",
|
||||||
mptr.blocks[0],
|
t->o.o.mdir.rbyd.blocks[0],
|
||||||
mptr.blocks[1]);
|
t->o.o.mdir.rbyd.blocks[1]);
|
||||||
return LFS_ERR_CORRUPT;
|
return LFS_ERR_CORRUPT;
|
||||||
}
|
}
|
||||||
if (t->u.mtortoise.step == (1U << t->u.mtortoise.power)) {
|
if (t->u.mtortoise.step == (1U << t->u.mtortoise.power)) {
|
||||||
t->u.mtortoise.mptr = mptr;
|
t->u.mtortoise.mptr = *lfsr_mdir_mptr(&t->o.o.mdir);
|
||||||
t->u.mtortoise.step = 0;
|
t->u.mtortoise.step = 0;
|
||||||
t->u.mtortoise.power += 1;
|
t->u.mtortoise.power += 1;
|
||||||
}
|
}
|
||||||
t->u.mtortoise.step += 1;
|
t->u.mtortoise.step += 1;
|
||||||
|
|
||||||
// fetch this mroot
|
|
||||||
err = lfsr_mdir_fetch(lfs, &t->o.o.mdir, -1, &mptr);
|
|
||||||
if (err) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tag_) {
|
if (tag_) {
|
||||||
*tag_ = LFSR_TAG_MDIR;
|
*tag_ = LFSR_TAG_MDIR;
|
||||||
}
|
}
|
||||||
@@ -9237,13 +9235,8 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t,
|
|||||||
// found an mdir?
|
// found an mdir?
|
||||||
} else if (tag == LFSR_TAG_MDIR) {
|
} else if (tag == LFSR_TAG_MDIR) {
|
||||||
// fetch this mdir
|
// fetch this mdir
|
||||||
lfsr_mptr_t mptr;
|
err = lfsr_data_fetchmdir(lfs, &data, 0,
|
||||||
err = lfsr_data_readmptr(lfs, &data, &mptr);
|
&t->o.o.mdir);
|
||||||
if (err) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = lfsr_mdir_fetch(lfs, &t->o.o.mdir, 0, &mptr);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user