Some small tweaks to mdir functions

- Added lfsr_mdir_lookupnext, for iteration through only a single mid.
  This is useful for MOVE attributes.

- Renamed LFSR_MDIR_MROOTANCHOR -> LFSR_MROOTANCHOR.

- Renamed functions that operate on mdir blocks lfsr_mdir_* ->
  lfsr_mblocks_*.

- Reordered arguments in lfsr_mdir_fetch.

- Renamed mrid_bits/mbid_weight -> mbits/mweight.
This commit is contained in:
Christopher Haster
2023-09-03 22:08:59 -05:00
parent f7900edc1c
commit cf90398197
4 changed files with 325 additions and 286 deletions
+89 -50
View File
@@ -1536,12 +1536,12 @@ static int lfsr_data_readecksum(lfs_t *lfs, lfsr_data_t *data,
/// Metadata-id things /// /// Metadata-id things ///
static inline lfs_size_t lfsr_mbidweight(lfs_t *lfs) { static inline lfs_size_t lfsr_mweight(lfs_t *lfs) {
return 1 << lfs->mrid_bits; return 1 << lfs->mbits;
} }
static inline lfs_ssize_t lfsr_mridmask(lfs_t *lfs) { static inline lfs_ssize_t lfsr_mridmask(lfs_t *lfs) {
return (1 << lfs->mrid_bits) - 1; return (1 << lfs->mbits) - 1;
} }
static inline lfs_ssize_t lfsr_mbidmask(lfs_t *lfs) { static inline lfs_ssize_t lfsr_mbidmask(lfs_t *lfs) {
@@ -1653,7 +1653,7 @@ static int lfsr_grm_todisk(lfs_t *lfs, const lfsr_grm_t *grm,
return 0; return 0;
} }
// needed in lfsr_grm_fromdisk // required by lfsr_grm_fromdisk
static inline bool lfsr_mtree_isinlined(lfs_t *lfs); static inline bool lfsr_mtree_isinlined(lfs_t *lfs);
static inline lfs_size_t lfsr_mtree_weight(lfs_t *lfs); static inline lfs_size_t lfsr_mtree_weight(lfs_t *lfs);
@@ -1677,8 +1677,9 @@ static int lfsr_data_readgrm(lfs_t *lfs, lfsr_data_t *data,
return err; return err;
} }
LFS_ASSERT(grm->rms[i] LFS_ASSERT(grm->rms[i] < lfs_smax32(
< lfs_smax32(lfsr_mtree_weight(lfs), lfsr_mbidweight(lfs))); lfsr_mtree_weight(lfs),
lfsr_mweight(lfs)));
} }
return 0; return 0;
@@ -2854,6 +2855,11 @@ failed:;
return err; return err;
} }
// required by lfsr_rbyd_appendattrs
static int lfsr_mdir_lookupnext(lfs_t *lfs, const lfsr_mdir_t *mdir,
lfs_ssize_t rid, lfsr_tag_t tag,
lfsr_tag_t *tag_, lfsr_data_t *data_);
static int lfsr_rbyd_appendattrs(lfs_t *lfs, lfsr_rbyd_t *rbyd, static int lfsr_rbyd_appendattrs(lfs_t *lfs, lfsr_rbyd_t *rbyd,
lfs_size_t bid, lfs_ssize_t start_rid, lfs_ssize_t end_rid, lfs_size_t bid, lfs_ssize_t start_rid, lfs_ssize_t end_rid,
const lfsr_attr_t *attrs, lfs_size_t attr_count) { const lfsr_attr_t *attrs, lfs_size_t attr_count) {
@@ -2891,16 +2897,14 @@ static int lfsr_rbyd_appendattrs(lfs_t *lfs, lfsr_rbyd_t *rbyd,
// skip the name tag, this is always replaced by upper layers // skip the name tag, this is always replaced by upper layers
lfsr_tag_t tag = LFSR_TAG_NAME + 0xff; lfsr_tag_t tag = LFSR_TAG_NAME + 0xff;
while (true) { while (true) {
lfs_ssize_t rid_;
lfsr_data_t data; lfsr_data_t data;
int err = lfsr_rbyd_lookupnext(lfs, &mdir->u.r.rbyd, int err = lfsr_mdir_lookupnext(lfs, mdir,
mdir->mid & lfsr_mridmask(lfs), lfsr_tag_next(tag), mdir->mid, lfsr_tag_next(tag),
&rid_, &tag, NULL, &data); &tag, &data);
if (err && err != LFS_ERR_NOENT) { if (err && err != LFS_ERR_NOENT) {
return err; return err;
} }
if (err == LFS_ERR_NOENT if (err == LFS_ERR_NOENT) {
|| rid_ != (mdir->mid & lfsr_mridmask(lfs))) {
break; break;
} }
@@ -4580,9 +4584,9 @@ static int lfsr_btree_traversal_next(lfs_t *lfs,
/// Metadata pair operations /// /// Metadata pair operations ///
// 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_MDIR_MROOTANCHOR ((const lfs_block_t[2]){0, 1}) #define LFSR_MROOTANCHOR ((const lfs_block_t[2]){0, 1})
static inline int lfsr_mdir_cmp( static inline int lfsr_mblocks_cmp(
const lfs_block_t a[static 2], const lfs_block_t a[static 2],
const lfs_block_t b[static 2]) { const lfs_block_t b[static 2]) {
// note these can be in either order // note these can be in either order
@@ -4594,13 +4598,21 @@ static inline int lfsr_mdir_cmp(
} }
} }
static inline bool lfsr_mdir_ismrootanchor( static inline bool lfsr_mblocks_ismrootanchor(
const lfs_block_t blocks[static 2]) { const lfs_block_t blocks[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 blocks[0] <= 1; return blocks[0] <= 1;
} }
static inline int lfsr_mdir_cmp(const lfsr_mdir_t *a, const lfsr_mdir_t *b) {
return lfsr_mblocks_cmp(a->u.m.blocks, b->u.m.blocks);
}
static inline bool lfsr_mdir_ismrootanchor(const lfsr_mdir_t *mdir) {
return lfsr_mblocks_ismrootanchor(mdir->u.m.blocks);
}
// 2 leb128 => 10 bytes (worst case) // 2 leb128 => 10 bytes (worst case)
#define LFSR_MDIR_DSIZE (5+5) #define LFSR_MDIR_DSIZE (5+5)
@@ -4667,7 +4679,7 @@ static bool lfsr_mdir_isopened(lfs_t *lfs,
// actual mdir functions // actual mdir functions
static int lfsr_mdir_fetch(lfs_t *lfs, lfsr_mdir_t *mdir, static int lfsr_mdir_fetch(lfs_t *lfs, lfsr_mdir_t *mdir,
const lfs_block_t blocks[static 2], lfs_ssize_t mid) { lfs_ssize_t mid, const lfs_block_t blocks[static 2]) {
// create a copy of blocks, this is so we can swap the blocks // create a copy of blocks, this is so we can swap the blocks
// to keep track of the current revision, this also prevents issues // to keep track of the current revision, this also prevents issues
// if blocks points to the blocks in the mdir // if blocks points to the blocks in the mdir
@@ -4713,6 +4725,34 @@ static int lfsr_mdir_fetch(lfs_t *lfs, lfsr_mdir_t *mdir,
return LFS_ERR_CORRUPT; return LFS_ERR_CORRUPT;
} }
static int lfsr_mdir_lookupnext(lfs_t *lfs, const lfsr_mdir_t *mdir,
lfs_ssize_t rid, lfsr_tag_t tag,
lfsr_tag_t *tag_, lfsr_data_t *data_) {
// TODO anything better?
rid = (rid == -1
? -1
: rid - (lfs_smax32(mdir->mid, 0) & lfsr_mbidmask(lfs)));
lfs_ssize_t rid_;
lfsr_tag_t tag__;
int err = lfsr_rbyd_lookupnext(lfs, &mdir->u.r.rbyd, rid, tag,
&rid_, &tag__, NULL, data_);
if (err) {
return err;
}
// this is very similar to lfsr_rbyd_lookupnext, but we error if
// lookupnext would change rids
if (rid_ != rid) {
return LFS_ERR_NOENT;
}
if (tag_) {
*tag_ = tag__;
}
return 0;
}
static int lfsr_mdir_lookup(lfs_t *lfs, const lfsr_mdir_t *mdir, static int lfsr_mdir_lookup(lfs_t *lfs, const lfsr_mdir_t *mdir,
lfs_ssize_t rid, lfsr_tag_t tag, lfs_ssize_t rid, lfsr_tag_t tag,
lfsr_tag_t *tag_, lfsr_data_t *data_) { lfsr_tag_t *tag_, lfsr_data_t *data_) {
@@ -4769,7 +4809,7 @@ static int lfsr_mtree_lookup(lfs_t *lfs, lfs_ssize_t mid, lfsr_mdir_t *mdir_) {
// looking up mroot? // looking up mroot?
if (lfsr_mtree_isinlined(lfs)) { if (lfsr_mtree_isinlined(lfs)) {
LFS_ASSERT(mid >= 0); LFS_ASSERT(mid >= 0);
LFS_ASSERT(mid < (lfs_ssize_t)lfsr_mbidweight(lfs)); LFS_ASSERT(mid < (lfs_ssize_t)lfsr_mweight(lfs));
mdir_->mid = mid; mdir_->mid = mid;
mdir_->u.m = lfs->mroot.u.m; mdir_->u.m = lfs->mroot.u.m;
return 0; return 0;
@@ -4796,25 +4836,25 @@ static int lfsr_mtree_lookup(lfs_t *lfs, lfs_ssize_t mid, lfsr_mdir_t *mdir_) {
} }
// fetch mdir // fetch mdir
return lfsr_mdir_fetch(lfs, mdir_, mdir_->u.m.blocks, mid); return lfsr_mdir_fetch(lfs, mdir_, mid, mdir_->u.m.blocks);
} }
} }
static int lfsr_mtree_parent(lfs_t *lfs, const lfs_block_t blocks[static 2], static int lfsr_mtree_parent(lfs_t *lfs, const lfs_block_t blocks[static 2],
lfsr_mdir_t *mparent_) { lfsr_mdir_t *mparent_) {
// if mdir is our initial 0x{0,1} blocks, we have no parent // if mdir is our initial 0x{0,1} blocks, we have no parent
if (lfsr_mdir_ismrootanchor(blocks)) { if (lfsr_mblocks_ismrootanchor(blocks)) {
return LFS_ERR_NOENT; return LFS_ERR_NOENT;
} }
// scan list of mroots for our requested pair // scan list of mroots for our requested pair
lfs_block_t blocks_[2] = { lfs_block_t blocks_[2] = {
LFSR_MDIR_MROOTANCHOR[0], LFSR_MROOTANCHOR[0],
LFSR_MDIR_MROOTANCHOR[1]}; LFSR_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, blocks_, -1); int err = lfsr_mdir_fetch(lfs, &mdir, -1, blocks_);
if (err) { if (err) {
return err; return err;
} }
@@ -4834,7 +4874,7 @@ static int lfsr_mtree_parent(lfs_t *lfs, const lfs_block_t blocks[static 2],
} }
// found our child? // found our child?
if (lfsr_mdir_cmp(blocks_, blocks) == 0) { if (lfsr_mblocks_cmp(blocks_, blocks) == 0) {
*mparent_ = mdir; *mparent_ = mdir;
return 0; return 0;
} }
@@ -4849,14 +4889,14 @@ static int lfsr_mtree_seek(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_off_t off) {
// we don't know how many rids are in each mdir until we fetch // we don't know how many rids are in each mdir until we fetch
while (rid >= mdir->u.m.weight) { while (rid >= mdir->u.m.weight) {
// end of mtree? // end of mtree?
if (bid+lfsr_mbidweight(lfs) >= lfsr_mtree_weight(lfs)) { if (bid+lfsr_mweight(lfs) >= lfsr_mtree_weight(lfs)) {
// if we hit the end of the mtree, park the mdir so all future // if we hit the end of the mtree, park the mdir so all future
// seeks return noent // seeks return noent
mdir->mid = bid + mdir->u.m.weight; mdir->mid = bid + mdir->u.m.weight;
return LFS_ERR_NOENT; return LFS_ERR_NOENT;
} }
bid += lfsr_mbidweight(lfs); bid += lfsr_mweight(lfs);
rid -= mdir->u.m.weight; rid -= mdir->u.m.weight;
int err = lfsr_mtree_lookup(lfs, bid, mdir); int err = lfsr_mtree_lookup(lfs, bid, mdir);
if (err) { if (err) {
@@ -5016,7 +5056,7 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir_,
if (mdir_->mid == -1 if (mdir_->mid == -1
|| (lfsr_mtree_isinlined(lfs) || (lfsr_mtree_isinlined(lfs)
&& reason == LFSR_MDIR_COMPACTING) && reason == LFSR_MDIR_COMPACTING)
|| lfsr_mdir_cmp(mdir_->u.m.blocks, mdir->u.m.blocks) == 0) { || lfsr_mdir_cmp(mdir_, mdir) == 0) {
err = lfsr_rbyd_appendgdelta(lfs, &mdir_->u.r.rbyd); err = lfsr_rbyd_appendgdelta(lfs, &mdir_->u.r.rbyd);
if (err) { if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE); LFS_ASSERT(err != LFS_ERR_RANGE);
@@ -5213,7 +5253,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// This makes it so the split logic is the same whether or not // This makes it so the split logic is the same whether or not
// we're uninlining. // we're uninlining.
int err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS( int err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS(
LFSR_ATTR(0, MDIR, +lfsr_mbidweight(lfs), NULL))); LFSR_ATTR(0, MDIR, +lfsr_mweight(lfs), NULL)));
if (err) { if (err) {
return err; return err;
} }
@@ -5280,7 +5320,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// update our mtree // update our mtree
int err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS( int err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS(
LFSR_ATTR(mdir_.mid | lfsr_mridmask(lfs), LFSR_ATTR(mdir_.mid | lfsr_mridmask(lfs),
RM, -lfsr_mbidweight(lfs), NULL))); RM, -lfsr_mweight(lfs), NULL)));
if (err) { if (err) {
return err; return err;
} }
@@ -5341,7 +5381,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
} else { } else {
// adjust our sibling's mid, do this here in case other sibling // adjust our sibling's mid, do this here in case other sibling
// was dropped // was dropped
msibling_.mid += lfsr_mbidweight(lfs); msibling_.mid += lfsr_mweight(lfs);
// update out mtree // update out mtree
@@ -5375,7 +5415,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
LFSR_ATTR(mdir_.mid | lfsr_mridmask(lfs), LFSR_ATTR(mdir_.mid | lfsr_mridmask(lfs),
MDIR, 0, BUF(mdir_buf, mdir_dsize)), MDIR, 0, BUF(mdir_buf, mdir_dsize)),
LFSR_ATTR((mdir_.mid | lfsr_mridmask(lfs))+1, LFSR_ATTR((mdir_.mid | lfsr_mridmask(lfs))+1,
BRANCH, +lfsr_mbidweight(lfs), DATA(split_data)), BRANCH, +lfsr_mweight(lfs), DATA(split_data)),
LFSR_ATTR(msibling_.mid | lfsr_mridmask(lfs), LFSR_ATTR(msibling_.mid | lfsr_mridmask(lfs),
MDIR, 0, BUF(msibling_buf, msibling_dsize)))); MDIR, 0, BUF(msibling_buf, msibling_dsize))));
if (err) { if (err) {
@@ -5401,7 +5441,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// update our mtree // update our mtree
int err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS( int err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS(
LFSR_ATTR(mdir->mid | lfsr_mridmask(lfs), LFSR_ATTR(mdir->mid | lfsr_mridmask(lfs),
RM, -lfsr_mbidweight(lfs), NULL))); RM, -lfsr_mweight(lfs), NULL)));
if (err) { if (err) {
return err; return err;
} }
@@ -5409,7 +5449,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
dirtymtree = true; dirtymtree = true;
// need to relocate? // need to relocate?
} else if (lfsr_mdir_cmp(mdir->u.m.blocks, mdir_.u.m.blocks) != 0) { } else if (lfsr_mdir_cmp(mdir, &mdir_) != 0) {
// relocate mroot // relocate mroot
if (mdir->mid == -1 || lfsr_mtree_isinlined(lfs)) { if (mdir->mid == -1 || lfsr_mtree_isinlined(lfs)) {
// if we're relocating our root, just mark the root as dirty // if we're relocating our root, just mark the root as dirty
@@ -5478,7 +5518,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
<= (lfs_ssize_t)mdir->u.m.weight); <= (lfs_ssize_t)mdir->u.m.weight);
if ((grm->rms[j] & lfsr_mridmask(lfs)) if ((grm->rms[j] & lfsr_mridmask(lfs))
>= (lfs_ssize_t)mdir_.u.m.weight) { >= (lfs_ssize_t)mdir_.u.m.weight) {
grm->rms[j] += lfsr_mbidweight(lfs) grm->rms[j] += lfsr_mweight(lfs)
- mdir_.u.m.weight; - mdir_.u.m.weight;
} }
// update mid if we had a split or drop // update mid if we had a split or drop
@@ -5534,9 +5574,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
return err; return err;
} }
dirtymroot = (lfsr_mdir_cmp( dirtymroot = (lfsr_mdir_cmp(&lfs->mroot, &mroot_) != 0);
lfs->mroot.u.m.blocks,
mroot_.u.m.blocks) != 0);
} }
// need to update mroot? tail recurse, updating mroots until a commit sticks // need to update mroot? tail recurse, updating mroots until a commit sticks
@@ -5577,7 +5615,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
mchildroot_[0] = mparentroot.u.m.blocks[0]; mchildroot_[0] = mparentroot.u.m.blocks[0];
mchildroot_[1] = mparentroot.u.m.blocks[1]; mchildroot_[1] = mparentroot.u.m.blocks[1];
dirtymroot = (lfsr_mdir_cmp( dirtymroot = (lfsr_mblocks_cmp(
mchildroot.u.m.blocks, mchildroot.u.m.blocks,
mchildroot_) != 0); mchildroot_) != 0);
} }
@@ -5585,7 +5623,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// uh oh, we ran out of mrootparents, need to extend mroot chain // uh oh, we ran out of mrootparents, need to extend mroot chain
if (dirtymroot) { if (dirtymroot) {
// mchildroot should be our initial mroot at this point // mchildroot should be our initial mroot at this point
LFS_ASSERT(lfsr_mdir_ismrootanchor(mchildroot.u.m.blocks)); LFS_ASSERT(lfsr_mdir_ismrootanchor(&mchildroot));
LFS_DEBUG("Extending mroot 0x{%"PRIx32",%"PRIx32"}" LFS_DEBUG("Extending mroot 0x{%"PRIx32",%"PRIx32"}"
" -> 0x{%"PRIx32",%"PRIx32"}" " -> 0x{%"PRIx32",%"PRIx32"}"
@@ -5713,7 +5751,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
>= (lfs_ssize_t)mdir_.u.m.weight) { >= (lfs_ssize_t)mdir_.u.m.weight) {
LFS_ASSERT(lfsr_btree_weight(&mtree_) LFS_ASSERT(lfsr_btree_weight(&mtree_)
!= lfsr_mtree_weight(lfs)); != lfsr_mtree_weight(lfs));
opened_mdir->mid += lfsr_mbidweight(lfs) opened_mdir->mid += lfsr_mweight(lfs)
- mdir_.u.m.weight; - mdir_.u.m.weight;
opened_mdir->u.m = msibling_.u.m; opened_mdir->u.m = msibling_.u.m;
} else { } else {
@@ -5736,7 +5774,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// TODO this can happen if we split+drop while removing this mid, // TODO this can happen if we split+drop while removing this mid,
// can we still assert for this? // can we still assert for this?
//LFS_ASSERT(lfsr_btree_weight(&mtree_) != lfsr_mtree_weight(lfs)); //LFS_ASSERT(lfsr_btree_weight(&mtree_) != lfsr_mtree_weight(lfs));
mdir->mid += lfsr_mbidweight(lfs) mdir->mid += lfsr_mweight(lfs)
- mdir_.u.m.weight; - mdir_.u.m.weight;
mdir->u.m = msibling_.u.m; mdir->u.m = msibling_.u.m;
} else { } else {
@@ -5794,7 +5832,7 @@ static int lfsr_mtree_namelookup(lfs_t *lfs,
return err; return err;
} }
LFS_ASSERT(tag == LFSR_TAG_MDIR); LFS_ASSERT(tag == LFSR_TAG_MDIR);
LFS_ASSERT(weight == lfsr_mbidweight(lfs)); LFS_ASSERT(weight == lfsr_mweight(lfs));
// decode mdir // decode mdir
err = lfsr_data_readmdir(lfs, &data, mdir.u.m.blocks); err = lfsr_data_readmdir(lfs, &data, mdir.u.m.blocks);
@@ -5803,7 +5841,7 @@ static int lfsr_mtree_namelookup(lfs_t *lfs,
} }
// fetch mdir // fetch mdir
err = lfsr_mdir_fetch(lfs, &mdir, mdir.u.m.blocks, bid-(weight-1)); err = lfsr_mdir_fetch(lfs, &mdir, bid-(weight-1), mdir.u.m.blocks);
if (err) { if (err) {
return err; return err;
} }
@@ -6004,7 +6042,7 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs,
if (traversal->mdir.u.r.rbyd.trunk == 0) { if (traversal->mdir.u.r.rbyd.trunk == 0) {
// fetch the first mroot 0x{0,1} // fetch the first mroot 0x{0,1}
int err = lfsr_mdir_fetch(lfs, &traversal->mdir, int err = lfsr_mdir_fetch(lfs, &traversal->mdir,
LFSR_MDIR_MROOTANCHOR, -1); -1, LFSR_MROOTANCHOR);
if (err) { if (err) {
return err; return err;
} }
@@ -6045,7 +6083,7 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs,
// inner nodes require checksums of their pointers, so creating // inner nodes require checksums of their pointers, so creating
// a valid cycle is actually quite difficult // a valid cycle is actually quite difficult
// //
if (lfsr_mdir_cmp( if (lfsr_mblocks_cmp(
traversal->mdir.u.m.blocks, traversal->mdir.u.m.blocks,
traversal->u.m.tortoise.blocks) == 0) { traversal->u.m.tortoise.blocks) == 0) {
LFS_ERROR("Cycle detected during mtree traversal " LFS_ERROR("Cycle detected during mtree traversal "
@@ -6067,7 +6105,7 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs,
// fetch this mroot // fetch this mroot
err = lfsr_mdir_fetch(lfs, &traversal->mdir, err = lfsr_mdir_fetch(lfs, &traversal->mdir,
traversal->mdir.u.m.blocks, -1); -1, traversal->mdir.u.m.blocks);
if (err) { if (err) {
return err; return err;
} }
@@ -6093,7 +6131,7 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs,
lfs->mtree = LFSR_BTREE_NULL; lfs->mtree = LFSR_BTREE_NULL;
} else if (tag == LFSR_TAG_MDIR) { } else if (tag == LFSR_TAG_MDIR) {
err = lfsr_data_readbtreeinlined(lfs, &data, err = lfsr_data_readbtreeinlined(lfs, &data,
LFSR_TAG_MDIR, lfsr_mbidweight(lfs), LFSR_TAG_MDIR, lfsr_mweight(lfs),
&lfs->mtree); &lfs->mtree);
if (err) { if (err) {
return err; return err;
@@ -6187,7 +6225,7 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs,
} }
err = lfsr_mdir_fetch(lfs, &traversal->mdir, err = lfsr_mdir_fetch(lfs, &traversal->mdir,
traversal->mdir.u.m.blocks, bid); bid, traversal->mdir.u.m.blocks);
if (err) { if (err) {
return err; return err;
} }
@@ -7366,8 +7404,9 @@ static int lfsr_fs_fixgrm(lfs_t *lfs) {
while (lfsr_grm_hasrm(&lfs->grm)) { while (lfsr_grm_hasrm(&lfs->grm)) {
// find our mdir // find our mdir
lfsr_mdir_t mdir; lfsr_mdir_t mdir;
LFS_ASSERT(lfs->grm.rms[0] LFS_ASSERT(lfs->grm.rms[0] < lfs_smax32(
< lfs_smax32(lfsr_mtree_weight(lfs), lfsr_mbidweight(lfs))); lfsr_mtree_weight(lfs),
lfsr_mweight(lfs)));
int err = lfsr_mtree_lookup(lfs, lfs->grm.rms[0], &mdir); int err = lfsr_mtree_lookup(lfs, lfs->grm.rms[0], &mdir);
if (err) { if (err) {
return err; return err;
@@ -10926,7 +10965,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
// Note we can't assume ~1/2 block utilization here, as an mdir may // Note we can't assume ~1/2 block utilization here, as an mdir may
// temporarily fill with more mids before compaction occurs. // temporarily fill with more mids before compaction occurs.
// //
lfs->mrid_bits = lfs_nlog2(lfs->cfg->block_size/16); lfs->mbits = lfs_nlog2(lfs->cfg->block_size/16);
// zero linked-lists of opened mdirs // zero linked-lists of opened mdirs
lfs->opened[LFS_TYPE_REG] = NULL; lfs->opened[LFS_TYPE_REG] = NULL;
+1 -1
View File
@@ -511,7 +511,7 @@ typedef struct lfs {
uint8_t pgrm[LFSR_GRM_DSIZE]; uint8_t pgrm[LFSR_GRM_DSIZE];
uint8_t dgrm[LFSR_GRM_DSIZE]; uint8_t dgrm[LFSR_GRM_DSIZE];
uint8_t mrid_bits; uint8_t mbits;
lfsr_mdir_t mroot; lfsr_mdir_t mroot;
lfsr_btree_t mtree; lfsr_btree_t mtree;
+3 -3
View File
@@ -109,7 +109,7 @@ code = '''
LFSR_ATTR(0, RM, -1, NULL))) => 0; LFSR_ATTR(0, RM, -1, NULL))) => 0;
lfsr_mdir_t mdir; lfsr_mdir_t mdir;
lfsr_mtree_lookup(&lfs, 0*lfsr_mbidweight(&lfs)+0, lfsr_mtree_lookup(&lfs, 0*lfsr_mweight(&lfs)+0,
&mdir) => 0; &mdir) => 0;
lfs_size_t count = 0; lfs_size_t count = 0;
@@ -146,8 +146,8 @@ code = '''
for (lfs_ssize_t mid = 0; for (lfs_ssize_t mid = 0;
mid < lfs_smax32( mid < lfs_smax32(
lfsr_mtree_weight(&lfs), lfsr_mtree_weight(&lfs),
lfsr_mbidweight(&lfs)); lfsr_mweight(&lfs));
mid += lfsr_mbidweight(&lfs)) { mid += lfsr_mweight(&lfs)) {
lfsr_mdir_t mdir; lfsr_mdir_t mdir;
lfsr_mtree_lookup(&lfs, mid, &mdir) => 0; lfsr_mtree_lookup(&lfs, mid, &mdir) => 0;
for (; (mdir.mid & lfsr_mridmask(&lfs)) for (; (mdir.mid & lfsr_mridmask(&lfs))
+232 -232
View File
File diff suppressed because it is too large Load Diff