Dropped lfsr_mptr_t as a struct

This replaces the lfsr_mptr_t struct with simple arrays.

The main motivation for this is C99's strict aliasing. It saves a
decent amount of stack to reference the mdir's internal block array as
an mptr directly, but we were only able to accomplish this in
lfsr_mdir_mptr by violating C99's strict aliasing rules.

The main downside of this is C's wonderful array-to-pointer decay
resulting in more implicit references and chances for things to get
clobbered (the original motivation for lfsr_mptr_t was due to bugs
introduced this way).

If I know one thing about C99's strict aliasing it's that it sure loves
to make code less safe.

No significant code changes, which is probably a good thing:

                     code          stack
  default before:   36436           2672
  default after:    36432 (-0.0%)   2672 (+0.0%)

  ckfetches before: 36674           2704
  ckfetches after:  36666 (-0.0%)   2704 (+0.0%)
This commit is contained in:
Christopher Haster
2024-08-14 16:00:37 -05:00
parent 770578d221
commit 2cefcbdddc
4 changed files with 69 additions and 73 deletions
+63 -63
View File
@@ -6557,26 +6557,24 @@ static inline lfsr_srid_t lfsr_mid_rid(const lfs_t *lfs, lfsr_smid_t mid) {
/// metadata-pointer things /// /// metadata-pointer things ///
// the mroot anchor, mdir 0x{0,1} is the entry point into the filesystem // the mroot anchor, mdir 0x{0,1} is the entry point into the filesystem
#define LFSR_MPTR_MROOTANCHOR() ((const lfsr_mptr_t){{0, 1}}) #define LFSR_MPTR_MROOTANCHOR() ((const lfs_block_t[2]){0, 1})
static inline int lfsr_mptr_cmp( static inline int lfsr_mptr_cmp(
const lfsr_mptr_t *a, const lfs_block_t a[static 2],
const lfsr_mptr_t *b) { const lfs_block_t b[static 2]) {
// note these can be in either order // note these can be in either order
if (lfs_max(a->blocks[0], a->blocks[1]) if (lfs_max(a[0], a[1]) != lfs_max(b[0], b[1])) {
!= lfs_max(b->blocks[0], b->blocks[1])) { return lfs_max(a[0], a[1]) - lfs_max(b[0], b[1]);
return lfs_max(a->blocks[0], a->blocks[1])
- lfs_max(b->blocks[0], b->blocks[1]);
} else { } else {
return lfs_min(a->blocks[0], a->blocks[1]) return lfs_min(a[0], a[1]) - lfs_min(b[0], b[1]);
- lfs_min(b->blocks[0], b->blocks[1]);
} }
} }
static inline bool lfsr_mptr_ismrootanchor(const lfsr_mptr_t *mptr) { static inline bool lfsr_mptr_ismrootanchor(
const lfs_block_t mptr[static 2]) {
// mrootanchor is always at 0x{0,1} // mrootanchor is always at 0x{0,1}
// just check that the first block is in mroot anchor range // just check that the first block is in mroot anchor range
return mptr->blocks[0] <= 1; return mptr[0] <= 1;
} }
// mptr encoding: // mptr encoding:
@@ -6594,15 +6592,15 @@ static inline bool lfsr_mptr_ismrootanchor(const lfsr_mptr_t *mptr) {
#define LFSR_DATA_MPTR(_mptr) \ #define LFSR_DATA_MPTR(_mptr) \
LFSR_DATA_MPTR_(_mptr, (uint8_t[LFSR_MPTR_DSIZE]){0}) LFSR_DATA_MPTR_(_mptr, (uint8_t[LFSR_MPTR_DSIZE]){0})
static lfsr_data_t lfsr_data_frommptr(const lfsr_mptr_t *mptr, static lfsr_data_t lfsr_data_frommptr(const lfs_block_t mptr[static 2],
uint8_t buffer[static LFSR_MPTR_DSIZE]) { uint8_t buffer[static LFSR_MPTR_DSIZE]) {
// blocks should not exceed 31-bits // blocks should not exceed 31-bits
LFS_ASSERT(mptr->blocks[0] <= 0x7fffffff); LFS_ASSERT(mptr[0] <= 0x7fffffff);
LFS_ASSERT(mptr->blocks[1] <= 0x7fffffff); LFS_ASSERT(mptr[1] <= 0x7fffffff);
lfs_ssize_t d = 0; lfs_ssize_t d = 0;
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
lfs_ssize_t d_ = lfs_toleb128(mptr->blocks[i], &buffer[d], 5); lfs_ssize_t d_ = lfs_toleb128(mptr[i], &buffer[d], 5);
if (d_ < 0) { if (d_ < 0) {
LFS_UNREACHABLE(); LFS_UNREACHABLE();
} }
@@ -6613,9 +6611,9 @@ static lfsr_data_t lfsr_data_frommptr(const lfsr_mptr_t *mptr,
} }
static int lfsr_data_readmptr(lfs_t *lfs, lfsr_data_t *data, static int lfsr_data_readmptr(lfs_t *lfs, lfsr_data_t *data,
lfsr_mptr_t *mptr) { lfs_block_t mptr[static 2]) {
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
int err = lfsr_data_readleb128(lfs, data, &mptr->blocks[i]); int err = lfsr_data_readleb128(lfs, data, &mptr[i]);
if (err) { if (err) {
return err; return err;
} }
@@ -7146,30 +7144,26 @@ static inline uint32_t lfsr_rev_inc(lfs_t *lfs, uint32_t rev) {
/// Metadata pair stuff /// /// Metadata pair stuff ///
// mdir convenience functions // mdir convenience functions
static inline const lfsr_mptr_t *lfsr_mdir_mptr(const lfsr_mdir_t *mdir) {
return (const lfsr_mptr_t*)mdir->rbyd.blocks;
}
static inline int lfsr_mdir_cmp(const lfsr_mdir_t *a, const lfsr_mdir_t *b) { static inline int lfsr_mdir_cmp(const lfsr_mdir_t *a, const lfsr_mdir_t *b) {
return lfsr_mptr_cmp(lfsr_mdir_mptr(a), lfsr_mdir_mptr(b)); return lfsr_mptr_cmp(a->rbyd.blocks, b->rbyd.blocks);
} }
static inline bool lfsr_mdir_ismrootanchor(const lfsr_mdir_t *mdir) { static inline bool lfsr_mdir_ismrootanchor(const lfsr_mdir_t *mdir) {
return lfsr_mptr_ismrootanchor(lfsr_mdir_mptr(mdir)); return lfsr_mptr_ismrootanchor(mdir->rbyd.blocks);
} }
// mdir operations // mdir operations
static int lfsr_mdir_fetch(lfs_t *lfs, lfsr_mdir_t *mdir, static int lfsr_mdir_fetch(lfs_t *lfs, lfsr_mdir_t *mdir,
lfsr_smid_t mid, const lfsr_mptr_t *mptr) { lfsr_smid_t mid, const lfs_block_t mptr[static 2]) {
// create a copy of blocks, this is so we can swap the blocks // create a copy of the mptr, both so we can swap the blocks to keep
// to keep track of the current revision, this also prevents issues // track of the current revision, and to prevents issues if mptr
// if blocks points to the blocks in the mdir // references the blocks in the mdir
lfs_block_t blocks_[2] = {mptr->blocks[0], mptr->blocks[1]}; lfs_block_t blocks[2] = {mptr[0], mptr[1]};
// read both revision counts, try to figure out which block // read both revision counts, try to figure out which block
// has the most recent revision // has the most recent revision
uint32_t revs[2] = {0, 0}; uint32_t revs[2] = {0, 0};
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
int err = lfsr_bd_read(lfs, blocks_[0], 0, 0, int err = lfsr_bd_read(lfs, blocks[0], 0, 0,
&revs[0], sizeof(uint32_t)); &revs[0], sizeof(uint32_t));
if (err && err != LFS_ERR_CORRUPT) { if (err && err != LFS_ERR_CORRUPT) {
return err; return err;
@@ -7179,14 +7173,14 @@ static int lfsr_mdir_fetch(lfs_t *lfs, lfsr_mdir_t *mdir,
if (i == 0 if (i == 0
|| err == LFS_ERR_CORRUPT || err == LFS_ERR_CORRUPT
|| lfs_scmp(revs[1], revs[0]) > 0) { || lfs_scmp(revs[1], revs[0]) > 0) {
LFS_SWAP(lfs_block_t, &blocks_[0], &blocks_[1]); LFS_SWAP(lfs_block_t, &blocks[0], &blocks[1]);
LFS_SWAP(uint32_t, &revs[0], &revs[1]); LFS_SWAP(uint32_t, &revs[0], &revs[1]);
} }
} }
// try to fetch rbyds in the order of most recent to least recent // try to fetch rbyds in the order of most recent to least recent
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
int err = lfsr_rbyd_fetch(lfs, &mdir->rbyd, blocks_[0], 0); int err = lfsr_rbyd_fetch(lfs, &mdir->rbyd, blocks[0], 0);
if (err && err != LFS_ERR_CORRUPT) { if (err && err != LFS_ERR_CORRUPT) {
return err; return err;
} }
@@ -7194,11 +7188,11 @@ static int lfsr_mdir_fetch(lfs_t *lfs, lfsr_mdir_t *mdir,
if (err != LFS_ERR_CORRUPT) { if (err != LFS_ERR_CORRUPT) {
mdir->mid = mid; mdir->mid = mid;
// keep track of other block for compactions // keep track of other block for compactions
mdir->rbyd.blocks[1] = blocks_[1]; mdir->rbyd.blocks[1] = blocks[1];
return 0; return 0;
} }
LFS_SWAP(lfs_block_t, &blocks_[0], &blocks_[1]); LFS_SWAP(lfs_block_t, &blocks[0], &blocks[1]);
LFS_SWAP(uint32_t, &revs[0], &revs[1]); LFS_SWAP(uint32_t, &revs[0], &revs[1]);
} }
@@ -7211,12 +7205,12 @@ static int lfsr_data_fetchmdir(lfs_t *lfs,
lfsr_mdir_t *mdir) { lfsr_mdir_t *mdir) {
// decode mptr and fetch // decode mptr and fetch
int err = lfsr_data_readmptr(lfs, data, int err = lfsr_data_readmptr(lfs, data,
(lfsr_mptr_t*)mdir->rbyd.blocks); mdir->rbyd.blocks);
if (err) { if (err) {
return err; return err;
} }
return lfsr_mdir_fetch(lfs, mdir, mid, lfsr_mdir_mptr(mdir)); return lfsr_mdir_fetch(lfs, mdir, mid, mdir->rbyd.blocks);
} }
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,
@@ -7324,9 +7318,10 @@ static int lfsr_mdir_suplookup(lfs_t *lfs, const lfsr_mdir_t *mdir,
#define LFSR_MTREE_NULL() ((lfsr_mtree_t){ \ #define LFSR_MTREE_NULL() ((lfsr_mtree_t){ \
.u.weight=(LFSR_MTREE_ISMPTR | 0)}) .u.weight=(LFSR_MTREE_ISMPTR | 0)})
#define LFSR_MTREE_MPTR(_mptr, _weight) ((lfsr_mtree_t){ \ #define LFSR_MTREE_MPTR(_block0, _block1, _weight) ((lfsr_mtree_t){ \
.u.mptr.weight=(LFSR_MTREE_ISMPTR | (_weight)), \ .u.mptr.weight=(LFSR_MTREE_ISMPTR | (_weight)), \
.u.mptr.mptr=_mptr}) .u.mptr.blocks[0]=_block0, \
.u.mptr.blocks[1]=_block1})
static inline bool lfsr_mtree_isnull(const lfsr_mtree_t *mtree) { static inline bool lfsr_mtree_isnull(const lfsr_mtree_t *mtree) {
return mtree->u.weight == (LFSR_MTREE_ISMPTR | 0); return mtree->u.weight == (LFSR_MTREE_ISMPTR | 0);
@@ -7352,7 +7347,7 @@ static inline int lfsr_mtree_cmp(
} else if (lfsr_mtree_isnull(a)) { } else if (lfsr_mtree_isnull(a)) {
return 0; return 0;
} else if (lfsr_mtree_ismptr(a)) { } else if (lfsr_mtree_ismptr(a)) {
return lfsr_mptr_cmp(&a->u.mptr.mptr, &b->u.mptr.mptr); return lfsr_mptr_cmp(a->u.mptr.blocks, b->u.mptr.blocks);
} else { } else {
return lfsr_btree_cmp(&a->u.btree, &b->u.btree); return lfsr_btree_cmp(&a->u.btree, &b->u.btree);
} }
@@ -7383,7 +7378,7 @@ static int lfsr_mtree_lookup(lfs_t *lfs, lfsr_smid_t mid,
// looking up direct mdir? // looking up direct mdir?
} else if (lfsr_mtree_ismptr(&lfs->mtree)) { } else if (lfsr_mtree_ismptr(&lfs->mtree)) {
// fetch mdir // fetch mdir
return lfsr_mdir_fetch(lfs, mdir_, mid, &lfs->mtree.u.mptr.mptr); return lfsr_mdir_fetch(lfs, mdir_, mid, lfs->mtree.u.mptr.blocks);
// look up mdir in actual mtree // look up mdir in actual mtree
} else { } else {
@@ -8169,17 +8164,19 @@ relocate:;
return 0; return 0;
} }
static int lfsr_mroot_parent(lfs_t *lfs, const lfsr_mptr_t *mptr, static int lfsr_mroot_parent(lfs_t *lfs, const lfs_block_t mptr[static 2],
lfsr_mdir_t *mparent_) { lfsr_mdir_t *mparent_) {
// we only call this when we actually have parents // we only call this when we actually have parents
LFS_ASSERT(!lfsr_mptr_ismrootanchor(mptr)); LFS_ASSERT(!lfsr_mptr_ismrootanchor(mptr));
// scan list of mroots for our requested pair // scan list of mroots for our requested pair
lfsr_mptr_t mptr_ = LFSR_MPTR_MROOTANCHOR(); lfs_block_t mptr_[2] = {
LFSR_MPTR_MROOTANCHOR()[0],
LFSR_MPTR_MROOTANCHOR()[1]};
while (true) { while (true) {
// fetch next possible superblock // fetch next possible superblock
lfsr_mdir_t mdir; lfsr_mdir_t mdir;
int err = lfsr_mdir_fetch(lfs, &mdir, -1, &mptr_); int err = lfsr_mdir_fetch(lfs, &mdir, -1, mptr_);
if (err) { if (err) {
return err; return err;
} }
@@ -8194,13 +8191,13 @@ static int lfsr_mroot_parent(lfs_t *lfs, const lfsr_mptr_t *mptr,
} }
// decode mdir // decode mdir
err = lfsr_data_readmptr(lfs, &data, &mptr_); err = lfsr_data_readmptr(lfs, &data, mptr_);
if (err) { if (err) {
return err; return err;
} }
// found our child? // found our child?
if (lfsr_mptr_cmp(&mptr_, mptr) == 0) { if (lfsr_mptr_cmp(mptr_, mptr) == 0) {
*mparent_ = mdir; *mparent_ = mdir;
return 0; return 0;
} }
@@ -8424,7 +8421,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
LFSR_ATTR( LFSR_ATTR(
LFSR_TAG_MDIR, +(1 << lfs->mdir_bits), LFSR_TAG_MDIR, +(1 << lfs->mdir_bits),
LFSR_DATA_MPTR_( LFSR_DATA_MPTR_(
lfsr_mdir_mptr(&mdir_[0]), mdir_[0].rbyd.blocks,
&mdir_buf[0*LFSR_MPTR_DSIZE])), &mdir_buf[0*LFSR_MPTR_DSIZE])),
LFSR_ATTR_CAT_( LFSR_ATTR_CAT_(
LFSR_TAG_NAME, +(1 << lfs->mdir_bits), LFSR_TAG_NAME, +(1 << lfs->mdir_bits),
@@ -8432,7 +8429,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
LFSR_ATTR( LFSR_ATTR(
LFSR_TAG_MDIR, 0, LFSR_TAG_MDIR, 0,
LFSR_DATA_MPTR_( LFSR_DATA_MPTR_(
lfsr_mdir_mptr(&mdir_[1]), mdir_[1].rbyd.blocks,
&mdir_buf[1*LFSR_MPTR_DSIZE])))); &mdir_buf[1*LFSR_MPTR_DSIZE]))));
if (err) { if (err) {
goto failed; goto failed;
@@ -8449,7 +8446,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
LFSR_ATTR( LFSR_ATTR(
LFSR_TAG_MDIR, 0, LFSR_TAG_MDIR, 0,
LFSR_DATA_MPTR_( LFSR_DATA_MPTR_(
lfsr_mdir_mptr(&mdir_[0]), mdir_[0].rbyd.blocks,
&mdir_buf[0*LFSR_MPTR_DSIZE])), &mdir_buf[0*LFSR_MPTR_DSIZE])),
LFSR_ATTR_CAT_( LFSR_ATTR_CAT_(
LFSR_TAG_NAME, +(1 << lfs->mdir_bits), LFSR_TAG_NAME, +(1 << lfs->mdir_bits),
@@ -8457,7 +8454,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
LFSR_ATTR( LFSR_ATTR(
LFSR_TAG_MDIR, 0, LFSR_TAG_MDIR, 0,
LFSR_DATA_MPTR_( LFSR_DATA_MPTR_(
lfsr_mdir_mptr(&mdir_[1]), mdir_[1].rbyd.blocks,
&mdir_buf[1*LFSR_MPTR_DSIZE])))); &mdir_buf[1*LFSR_MPTR_DSIZE]))));
if (err) { if (err) {
goto failed; goto failed;
@@ -8510,7 +8507,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// new mtree? // new mtree?
if (lfsr_mtree_ismptr(&lfs->mtree)) { if (lfsr_mtree_ismptr(&lfs->mtree)) {
mtree_ = LFSR_MTREE_MPTR( mtree_ = LFSR_MTREE_MPTR(
*lfsr_mdir_mptr(&mdir_[0]), mdir_[0].rbyd.blocks[0],
mdir_[0].rbyd.blocks[1],
1 << lfs->mdir_bits); 1 << lfs->mdir_bits);
} else { } else {
@@ -8524,7 +8522,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
LFSR_ATTR( LFSR_ATTR(
LFSR_TAG_MDIR, 0, LFSR_TAG_MDIR, 0,
LFSR_DATA_MPTR_( LFSR_DATA_MPTR_(
lfsr_mdir_mptr(&mdir_[0]), mdir_[0].rbyd.blocks,
mdir_buf)))); mdir_buf))));
if (err) { if (err) {
goto failed; goto failed;
@@ -8594,7 +8592,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
(lfsr_mtree_ismptr(&mtree_)) (lfsr_mtree_ismptr(&mtree_))
? LFSR_ATTR( ? LFSR_ATTR(
LFSR_TAG_SUB | LFSR_TAG_MDIR, 0, LFSR_TAG_SUB | LFSR_TAG_MDIR, 0,
LFSR_DATA_MPTR_(&mtree_.u.mptr.mptr, mtree_buf)) LFSR_DATA_MPTR_(mtree_.u.mptr.blocks, mtree_buf))
: LFSR_ATTR( : LFSR_ATTR(
LFSR_TAG_SUB | LFSR_TAG_MTREE, 0, LFSR_TAG_SUB | LFSR_TAG_MTREE, 0,
LFSR_DATA_BTREE_(&mtree_.u.btree, mtree_buf)), LFSR_DATA_BTREE_(&mtree_.u.btree, mtree_buf)),
@@ -8619,7 +8617,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
&& !lfsr_mdir_ismrootanchor(&mrootchild)) { && !lfsr_mdir_ismrootanchor(&mrootchild)) {
// find the mroot's parent // find the mroot's parent
lfsr_mdir_t mrootparent_; lfsr_mdir_t mrootparent_;
err = lfsr_mroot_parent(lfs, lfsr_mdir_mptr(&mrootchild), err = lfsr_mroot_parent(lfs, mrootchild.rbyd.blocks,
&mrootparent_); &mrootparent_);
if (err) { if (err) {
LFS_ASSERT(err != LFS_ERR_NOENT); LFS_ASSERT(err != LFS_ERR_NOENT);
@@ -8647,7 +8645,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
LFSR_ATTR( LFSR_ATTR(
LFSR_TAG_MROOT, 0, LFSR_TAG_MROOT, 0,
LFSR_DATA_MPTR_( LFSR_DATA_MPTR_(
lfsr_mdir_mptr(&mrootchild_), mrootchild_.rbyd.blocks,
mrootchild_buf)))); mrootchild_buf))));
if (err) { if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE); LFS_ASSERT(err != LFS_ERR_RANGE);
@@ -8699,7 +8697,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
LFSR_ATTR( LFSR_ATTR(
LFSR_TAG_MROOT, 0, LFSR_TAG_MROOT, 0,
LFSR_DATA_MPTR_( LFSR_DATA_MPTR_(
lfsr_mdir_mptr(&mrootchild_), mrootchild_.rbyd.blocks,
mrootchild_buf)))); mrootchild_buf))));
if (err) { if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE); LFS_ASSERT(err != LFS_ERR_RANGE);
@@ -8917,7 +8915,7 @@ static int lfsr_mtree_namelookup(lfs_t *lfs,
// direct mdir? // direct mdir?
} else if (lfsr_mtree_ismptr(&lfs->mtree)) { } else if (lfsr_mtree_ismptr(&lfs->mtree)) {
int err = lfsr_mdir_fetch(lfs, &mdir, 0, &lfs->mtree.u.mptr.mptr); int err = lfsr_mdir_fetch(lfs, &mdir, 0, lfs->mtree.u.mptr.blocks);
if (err) { if (err) {
return err; return err;
} }
@@ -9141,7 +9139,7 @@ enum {
.o.o.mdir.rbyd.blocks={-1,-1}, \ .o.o.mdir.rbyd.blocks={-1,-1}, \
.o.bshrub.u.bshrub.blocks={-1}, \ .o.bshrub.u.bshrub.blocks={-1}, \
.ot=NULL, \ .ot=NULL, \
.u.mtortoise.mptr={{0, 0}}, \ .u.mtortoise.blocks={0, 0}, \
.u.mtortoise.step=0, \ .u.mtortoise.step=0, \
.u.mtortoise.power=0}) .u.mtortoise.power=0})
@@ -9157,7 +9155,7 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t,
case LFSR_TSTATE_MROOTANCHOR:; case LFSR_TSTATE_MROOTANCHOR:;
// fetch the first mroot 0x{0,1} // fetch the first mroot 0x{0,1}
int err = lfsr_mdir_fetch(lfs, &t->o.o.mdir, int err = lfsr_mdir_fetch(lfs, &t->o.o.mdir,
-1, &LFSR_MPTR_MROOTANCHOR()); -1, LFSR_MPTR_MROOTANCHOR());
if (err) { if (err) {
return err; return err;
} }
@@ -9209,8 +9207,8 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t,
// so creating a valid cycle is actually quite difficult // so creating a valid cycle is actually quite difficult
// //
if (lfsr_mptr_cmp( if (lfsr_mptr_cmp(
lfsr_mdir_mptr(&t->o.o.mdir), t->o.o.mdir.rbyd.blocks,
&t->u.mtortoise.mptr) == 0) { t->u.mtortoise.blocks) == 0) {
LFS_ERROR("Cycle detected during mtree traversal " LFS_ERROR("Cycle detected during mtree traversal "
"0x{%"PRIx32",%"PRIx32"}", "0x{%"PRIx32",%"PRIx32"}",
t->o.o.mdir.rbyd.blocks[0], t->o.o.mdir.rbyd.blocks[0],
@@ -9218,7 +9216,8 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t,
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 = *lfsr_mdir_mptr(&t->o.o.mdir); t->u.mtortoise.blocks[0] = t->o.o.mdir.rbyd.blocks[0];
t->u.mtortoise.blocks[1] = t->o.o.mdir.rbyd.blocks[1];
t->u.mtortoise.step = 0; t->u.mtortoise.step = 0;
t->u.mtortoise.power += 1; t->u.mtortoise.power += 1;
} }
@@ -13376,7 +13375,8 @@ static int lfsr_mountinited(lfs_t *lfs) {
// found a direct mdir? keep track of this // found a direct mdir? keep track of this
if (lfsr_mtree_isnull(&lfs->mtree)) { if (lfsr_mtree_isnull(&lfs->mtree)) {
lfs->mtree = LFSR_MTREE_MPTR( lfs->mtree = LFSR_MTREE_MPTR(
*lfsr_mdir_mptr(mdir), mdir->rbyd.blocks[0],
mdir->rbyd.blocks[1],
(1 << lfs->mdir_bits)); (1 << lfs->mdir_bits));
} }
} }
@@ -14288,8 +14288,8 @@ static int lfsr_traversal_rewind_(lfs_t *lfs, lfsr_traversal_t *t) {
t->o.bshrub.u.bshrub.weight = 0; t->o.bshrub.u.bshrub.weight = 0;
t->o.bshrub.u.bshrub.blocks[0] = -1; t->o.bshrub.u.bshrub.blocks[0] = -1;
t->ot = NULL; t->ot = NULL;
t->u.mtortoise.mptr.blocks[0] = 0; t->u.mtortoise.blocks[0] = 0;
t->u.mtortoise.mptr.blocks[1] = 0; t->u.mtortoise.blocks[1] = 0;
t->u.mtortoise.step = 0; t->u.mtortoise.step = 0;
t->u.mtortoise.power = 0; t->u.mtortoise.power = 0;
+2 -6
View File
@@ -536,10 +536,6 @@ typedef struct {
lfs_size_t estimate; lfs_size_t estimate;
} lfsr_shrub_t; } lfsr_shrub_t;
typedef struct lfsr_mptr {
lfs_block_t blocks[2];
} lfsr_mptr_t;
typedef struct lfsr_mdir { typedef struct lfsr_mdir {
lfsr_smid_t mid; lfsr_smid_t mid;
lfsr_rbyd_t rbyd; lfsr_rbyd_t rbyd;
@@ -706,7 +702,7 @@ typedef struct lfsr_traversal {
union { union {
// cycle detection state, only valid when traversing the mroot chain // cycle detection state, only valid when traversing the mroot chain
struct { struct {
lfsr_mptr_t mptr; lfs_block_t blocks[2];
lfs_block_t step; lfs_block_t step;
uint8_t power; uint8_t power;
} mtortoise; } mtortoise;
@@ -740,7 +736,7 @@ typedef struct lfsr_mtree {
lfsr_mid_t weight; lfsr_mid_t weight;
struct { struct {
lfsr_mid_t weight; lfsr_mid_t weight;
lfsr_mptr_t mptr; lfs_block_t blocks[2];
} mptr; } mptr;
lfsr_btree_t btree; lfsr_btree_t btree;
} u; } u;
+1 -1
View File
@@ -4326,7 +4326,7 @@ code = '''
lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS(
LFSR_ATTR( LFSR_ATTR(
LFSR_TAG_MROOT, 0, LFSR_TAG_MROOT, 0,
LFSR_DATA_MPTR(&LFSR_MPTR_MROOTANCHOR())))) => 0; LFSR_DATA_MPTR(LFSR_MPTR_MROOTANCHOR())))) => 0;
// technically, cycle detection only needs to work when we're validating // technically, cycle detection only needs to work when we're validating
lfsr_traversal_t t = LFSR_TRAVERSAL( lfsr_traversal_t t = LFSR_TRAVERSAL(
+3 -3
View File
@@ -5429,7 +5429,7 @@ code = '''
// we need internals to check this // we need internals to check this
lfsr_mdir_t mrootanchor; lfsr_mdir_t mrootanchor;
lfsr_mdir_fetch(&lfs, &mrootanchor, lfsr_mdir_fetch(&lfs, &mrootanchor,
-1, &LFSR_MPTR_MROOTANCHOR()) => 0; -1, LFSR_MPTR_MROOTANCHOR()) => 0;
if (lfsr_rbyd_eoff(&mrootanchor.rbyd) > GC_COMPACT_THRESH) { if (lfsr_rbyd_eoff(&mrootanchor.rbyd) > GC_COMPACT_THRESH) {
break; break;
} }
@@ -5474,7 +5474,7 @@ code = '''
// mrootanchor should have been compacted // mrootanchor should have been compacted
lfsr_mdir_t mrootanchor; lfsr_mdir_t mrootanchor;
lfsr_mdir_fetch(&lfs, &mrootanchor, lfsr_mdir_fetch(&lfs, &mrootanchor,
-1, &LFSR_MPTR_MROOTANCHOR()) => 0; -1, LFSR_MPTR_MROOTANCHOR()) => 0;
assert(lfsr_rbyd_eoff(&mrootanchor.rbyd) <= GC_COMPACT_THRESH); assert(lfsr_rbyd_eoff(&mrootanchor.rbyd) <= GC_COMPACT_THRESH);
// but because we mutated, we're still marked as uncompacted // but because we mutated, we're still marked as uncompacted
@@ -5496,7 +5496,7 @@ code = '''
// mrootanchor should have been compacted // mrootanchor should have been compacted
lfsr_mdir_fetch(&lfs, &mrootanchor, lfsr_mdir_fetch(&lfs, &mrootanchor,
-1, &LFSR_MPTR_MROOTANCHOR()) => 0; -1, LFSR_MPTR_MROOTANCHOR()) => 0;
assert(lfsr_rbyd_eoff(&mrootanchor.rbyd) <= GC_COMPACT_THRESH); assert(lfsr_rbyd_eoff(&mrootanchor.rbyd) <= GC_COMPACT_THRESH);
// uncompacted flag should have been cleared // uncompacted flag should have been cleared