diff --git a/lfs.c b/lfs.c index 7d7071a6..8a0a8a2f 100644 --- a/lfs.c +++ b/lfs.c @@ -1257,11 +1257,8 @@ typedef struct lfsr_attr { union { // data, either on-disk or in-device lfsr_data_t data; - // a move of all attrs from an rbyd+rid - struct { - const lfsr_rbyd_t *rbyd; - lfs_ssize_t rid; - } move; + // a move of all attrs from an mdir entry + const lfsr_mdir_t *mdir; // a grm update, note this is mutable! we may update // the grm during mdir commits lfsr_grm_t *grm; @@ -1274,11 +1271,11 @@ typedef struct lfsr_attr { #define LFSR_ATTR_DATA(_id, _type, _delta, _data) \ LFSR_ATTR_DATA_(_id, LFSR_TAG_##_type, _delta, _data) -#define LFSR_ATTR_MOVE_(_new_id, _type, _delta, _rbyd, _old_id) \ - ((const lfsr_attr_t){_new_id, _type, _delta, {.move={_rbyd, _old_id}}}) +#define LFSR_ATTR_MOVE_(_new_id, _type, _delta, _mdir) \ + ((const lfsr_attr_t){_new_id, _type, _delta, {.mdir=_mdir}}) -#define LFSR_ATTR_MOVE(_new_id, _type, _delta, _rbyd, _old_id) \ - LFSR_ATTR_MOVE_(_new_id, LFSR_TAG_##_type, _delta, _rbyd, _old_id) +#define LFSR_ATTR_MOVE(_new_id, _type, _delta, _mdir) \ + LFSR_ATTR_MOVE_(_new_id, LFSR_TAG_##_type, _delta, _mdir) #define LFSR_ATTR_GRM_(_new_id, _type, _delta, _grm) \ ((const lfsr_attr_t){_new_id, _type, _delta, {.grm=_grm}}) @@ -1531,6 +1528,9 @@ static lfs_ssize_t lfsr_fcrc_fromdisk(lfs_t *lfs, lfsr_fcrc_t *fcrc, // lfs->mlist = mlist; //} +/// Metadata-id things /// + +#define LFSR_MID(_bid, _rid) ((lfsr_mid_t){_bid, _rid}) /// Global-state things /// @@ -1581,25 +1581,22 @@ static int lfsr_gdelta_xor(lfs_t *lfs, // GRM (global remove) things static inline bool lfsr_grm_hasrm(const lfsr_grm_t *grm) { - return grm->rms[0].rid != -1; + return grm->mids[0].rid != -1; } static inline uint8_t lfsr_grm_count(const lfsr_grm_t *grm) { - return (grm->rms[0].rid != -1) + (grm->rms[1].rid != -1); + return (grm->mids[0].rid != -1) + (grm->mids[1].rid != -1); } -static inline void lfsr_grm_pushrm(lfsr_grm_t *grm, - lfs_size_t mid, lfs_size_t rid) { - LFS_ASSERT(grm->rms[1].rid == -1); - grm->rms[1] = grm->rms[0]; - grm->rms[0].mid = mid; - grm->rms[0].rid = rid; +static inline void lfsr_grm_pushrm(lfsr_grm_t *grm, lfsr_mid_t mid) { + LFS_ASSERT(grm->mids[1].rid == -1); + grm->mids[1] = grm->mids[0]; + grm->mids[0] = mid; } static inline void lfsr_grm_poprm(lfsr_grm_t *grm) { - grm->rms[0] = grm->rms[1]; - grm->rms[1].mid = -1; - grm->rms[1].rid = -1; + grm->mids[0] = grm->mids[1]; + grm->mids[1] = LFSR_MID(-1, -1); } static int lfsr_grm_todisk(lfs_t *lfs, const lfsr_grm_t *grm, @@ -1619,13 +1616,13 @@ static int lfsr_grm_todisk(lfs_t *lfs, const lfsr_grm_t *grm, for (uint8_t i = 0; i < count; i++) { // map mid=-1 (mroot) to mid=0 lfs_ssize_t d_ = lfs_toleb128( - lfs_smax32(grm->rms[i].mid, 0), &buffer[d], 5); + lfs_smax32(grm->mids[i].bid, 0), &buffer[d], 3); if (d_ < 0) { return d_; } d += d_; - d_ = lfs_toleb128(grm->rms[i].rid, &buffer[d], 5); + d_ = lfs_toleb128(grm->mids[i].rid, &buffer[d], 3); if (d_ < 0) { return d_; } @@ -1647,21 +1644,19 @@ static int lfsr_grm_fromdisk(lfs_t *lfs, lfsr_grm_t *grm, d += 1; // clear first - grm->rms[0].mid = -1; - grm->rms[0].rid = -1; - grm->rms[1].mid = -1; - grm->rms[1].rid = -1; + grm->mids[0] = LFSR_MID(-1, -1); + grm->mids[1] = LFSR_MID(-1, -1); LFS_ASSERT(count <= 2); for (uint8_t i = 0; i < count; i++) { - lfs_size_t mid; - lfs_ssize_t d_ = lfs_fromleb128(&mid, &buffer[d], LFSR_GRM_DSIZE-d); + lfs_size_t bid; + lfs_ssize_t d_ = lfs_fromleb128(&bid, &buffer[d], LFSR_GRM_DSIZE-d); if (d_ < 0) { return d_; } d += d_; // TODO should these checks be in lfsr_data_readleb128? - LFS_ASSERT(mid < 0x7fffffff); + LFS_ASSERT(bid <= 0x7fff); lfs_size_t rid; d_ = lfs_fromleb128(&rid, &buffer[d], LFSR_GRM_DSIZE-d); @@ -1670,12 +1665,13 @@ static int lfsr_grm_fromdisk(lfs_t *lfs, lfsr_grm_t *grm, } d += d_; // TODO should these checks be in lfsr_data_readleb128? - LFS_ASSERT(rid < 0x7fffffff); + LFS_ASSERT(rid < 0x7fff); // adjust mid if mtree is inlined - LFS_ASSERT(lfsr_mtree_isinlined(lfs) || mid < lfsr_mtree_weight(lfs)); - grm->rms[i].mid = lfs_smin32(mid, lfsr_mtree_weight(lfs)-1); - grm->rms[i].rid = rid; + LFS_ASSERT(lfsr_mtree_isinlined(lfs) || bid < lfsr_mtree_weight(lfs)); + grm->mids[i] = LFSR_MID( + lfs_smin32(bid, lfsr_mtree_weight(lfs)-1), + rid); } return 0; @@ -2746,13 +2742,15 @@ static int lfsr_rbyd_appendall(lfs_t *lfs, lfsr_rbyd_t *rbyd, while (true) { lfs_ssize_t rid; lfsr_data_t data; - int err = lfsr_rbyd_lookupnext(lfs, attrs[i].d.move.rbyd, - attrs[i].d.move.rid, lfsr_tag_next(tag), + int err = lfsr_rbyd_lookupnext(lfs, + &attrs[i].d.mdir->m.rbyd, + attrs[i].d.mdir->mid.rid, lfsr_tag_next(tag), &rid, &tag, NULL, &data); if (err && err != LFS_ERR_NOENT) { return err; } - if (err == LFS_ERR_NOENT || rid != attrs[i].d.move.rid) { + if (err == LFS_ERR_NOENT + || rid != attrs[i].d.mdir->mid.rid) { break; } @@ -5084,7 +5082,7 @@ static bool lfsr_mdir_isopened(lfs_t *lfs, // actual mdir functions -static int lfsr_mdir_alloc(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t mid) { +static int lfsr_mdir_alloc(lfs_t *lfs, lfsr_mdir_t *mdir, lfsr_mid_t mid) { // allocate two blocks lfs_block_t blocks[2]; for (int i = 0; i < 2; i++) { @@ -5127,7 +5125,7 @@ static int lfsr_mdir_alloc(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t mid) { } static int lfsr_mdir_fetch(lfs_t *lfs, lfsr_mdir_t *mdir, - lfsr_mptr_t mptr, lfs_ssize_t mid, lfs_ssize_t rid) { + lfsr_mptr_t mptr, lfsr_mid_t mid) { // read both revision counts, try to figure out which block // has the most recent revision uint32_t revs[2] = {0, 0}; @@ -5156,7 +5154,6 @@ static int lfsr_mdir_fetch(lfs_t *lfs, lfsr_mdir_t *mdir, if (!err) { mdir->mid = mid; - mdir->rid = rid; // keep track of other block for compactions mdir->m.redund_block = mptr.blocks[1]; return 0; @@ -5224,16 +5221,14 @@ static inline lfs_size_t lfsr_mtree_weight(lfs_t *lfs) { return lfsr_btree_weight(&lfs->mtree); } -static int lfsr_mtree_lookup(lfs_t *lfs, lfs_ssize_t mid, lfs_ssize_t rid, - lfsr_mdir_t *mdir_) { +static int lfsr_mtree_lookup(lfs_t *lfs, lfsr_mid_t mid, lfsr_mdir_t *mdir_) { // TODO should we really allow -1=>mroot lookup? - LFS_ASSERT(mid >= -1); - LFS_ASSERT(mid < (lfs_ssize_t)lfsr_mtree_weight(lfs)); + LFS_ASSERT(mid.bid >= -1); + LFS_ASSERT(mid.bid < (lfs_ssize_t)lfsr_mtree_weight(lfs)); // looking up mroot? - if (mid < 0) { + if (mid.bid < 0) { mdir_->mid = mid; - mdir_->rid = rid; mdir_->m = lfs->mroot.m; return 0; @@ -5241,7 +5236,7 @@ static int lfsr_mtree_lookup(lfs_t *lfs, lfs_ssize_t mid, lfs_ssize_t rid, } else { lfsr_tag_t tag; lfsr_data_t data; - int err = lfsr_btree_lookup(lfs, &lfs->mtree, mid, + int err = lfsr_btree_lookup(lfs, &lfs->mtree, mid.bid, &tag, NULL, &data); if (err) { return err; @@ -5256,7 +5251,7 @@ static int lfsr_mtree_lookup(lfs_t *lfs, lfs_ssize_t mid, lfs_ssize_t rid, } // fetch mdir - return lfsr_mdir_fetch(lfs, mdir_, mptr, mid, rid); + return lfsr_mdir_fetch(lfs, mdir_, mptr, mid); } } @@ -5272,7 +5267,7 @@ static int lfsr_mtree_parent(lfs_t *lfs, lfsr_mptr_t mchild, lfsr_mdir_t mdir; while (true) { // fetch next possible superblock - int err = lfsr_mdir_fetch(lfs, &mdir, mptr, -1, -1); + int err = lfsr_mdir_fetch(lfs, &mdir, mptr, LFSR_MID(-1, -1)); if (err) { return err; } @@ -5302,28 +5297,28 @@ static int lfsr_mtree_parent(lfs_t *lfs, lfsr_mptr_t mchild, static int lfsr_mtree_seek(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_off_t off) { // calculate new rid - lfs_ssize_t rid_ = mdir->rid + off; + lfs_ssize_t rid_ = mdir->mid.rid + off; // lookup mdirs until we find our rid, we need to do this because // we don't know how many rids are in each mdir until we fetch while (rid_ >= (lfs_ssize_t)mdir->m.rbyd.weight) { - lfs_ssize_t mid_ = mdir->mid + 1; + lfsr_smbid_t bid_ = mdir->mid.bid + 1; // end of mtree? - if (mid_ >= (lfs_ssize_t)lfsr_mtree_weight(lfs)) { + if (bid_ >= (lfs_ssize_t)lfsr_mtree_weight(lfs)) { // TODO is this needed? // make sure to update rid even if we error so seek will always // return noent after the first noent - mdir->rid = rid_; + mdir->mid.rid = rid_; return LFS_ERR_NOENT; } rid_ -= mdir->m.rbyd.weight; - int err = lfsr_mtree_lookup(lfs, mid_, rid_, mdir); + int err = lfsr_mtree_lookup(lfs, LFSR_MID(bid_, rid_), mdir); if (err) { return err; } } - mdir->rid = rid_; + mdir->mid.rid = rid_; return 0; } @@ -5360,8 +5355,8 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir_, // TODO rev things && (rev + 1) % lfs->cfg->block_cycles == 0))) { // allocate a new mdir for relocation - err = lfsr_mdir_alloc(lfs, mdir_, - (reason >= 0 ? reason : mdir_->mid)); + err = lfsr_mdir_alloc(lfs, mdir_, LFSR_MID( + (reason >= 0 ? reason : mdir->mid.bid), -1)); if (err) { return err; } @@ -5443,7 +5438,7 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir_, // drop commit if weight goes to zero - if (mdir_->mid >= 0 && mdir_->m.rbyd.weight == 0) { + if (mdir_->mid.bid >= 0 && mdir_->m.rbyd.weight == 0) { // TODO should we just make our pcache not assert? // drop our pcache, we're not going to complete this commit lfs_cache_zero(lfs, &lfs->pcache); @@ -5455,7 +5450,7 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir_, // // this pushes gstate up into the mroot when relocating, and // helps avoid corner case issues when splitting/dropping - if (mdir_->mid == -1 || lfsr_mdir_cmp(mdir_, mdir) == 0) { + if (mdir_->mid.bid == -1 || lfsr_mdir_cmp(mdir_, mdir) == 0) { err = lfsr_rbyd_appendgdelta(lfs, &mdir_->m.rbyd); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); @@ -5477,7 +5472,7 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir_, // TODO avoid duplicate conditions somehow? // success? gstate is committed - if (mdir_->mid == -1 || lfsr_mdir_cmp(mdir_, mdir) == 0) { + if (mdir_->mid.bid == -1 || lfsr_mdir_cmp(mdir_, mdir) == 0) { lfsr_fs_flushgdelta(lfs); } } @@ -5506,7 +5501,7 @@ static int lfsr_mdir_commit_(lfs_t *lfs, lfsr_mdir_t *mdir, } // drop commit if weight goes to zero - if (mdir_.mid >= 0 && mdir_.m.rbyd.weight == 0) { + if (mdir_.mid.bid >= 0 && mdir_.m.rbyd.weight == 0) { // TODO move this up into lfsr_mdir_commit? // consume gstate so we don't lose any info int err = lfsr_fs_consumegdelta(lfs, mdir); @@ -5582,7 +5577,7 @@ compact:; static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, const lfsr_attr_t *attrs, lfs_size_t attr_count) { LFS_ASSERT(!lfsr_mdir_isdropped(mdir)); - LFS_ASSERT(mdir->mid == -1 || mdir->m.rbyd.weight > 0); + LFS_ASSERT(mdir->mid.bid == -1 || mdir->m.rbyd.weight > 0); // parse out any pending gstate, these will get automatically xored // with on-disk gdeltas in lower-level functions @@ -5620,8 +5615,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // // TODO wait, do we need to update lfs->mroot and mdir eagerly // for the same reason? - lfsr_mdir_t mroot_ = (mdir->mid == -1 ? mdir_ : lfs->mroot); - lfsr_mdir_t msibling_ = {.m.rbyd.weight=0}; + lfsr_mdir_t mroot_ = (mdir->mid.bid == -1 ? mdir_ : lfs->mroot); + lfsr_mdir_t msibling_ = {.m.rbyd.trunk=0}; lfsr_btree_t mtree_ = lfs->mtree; bool dirtymroot = false; bool dirtymtree = false; @@ -5630,7 +5625,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, if (err == LFS_ERR_RANGE) { // if we're the mroot, create a new mtree, assume the upper layers // will take care of grafting our mtree into the mroot as needed - if (mdir->mid == -1) { + if (mdir->mid.bid == -1) { // Create a null entry in our btree first. Don't worry! Thanks // to inlining this doesn't allocate anything yet. // @@ -5662,8 +5657,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, } // compact into new mdir tags < split_id - lfs_ssize_t mid = lfs_smax32(mdir->mid, 0); - int err = lfsr_mdir_compact_(lfs, &mdir_, mid, 0, split_id, + lfsr_smbid_t mbid = lfs_smax32(mdir->mid.bid, 0); + int err = lfsr_mdir_compact_(lfs, &mdir_, mbid, 0, split_id, mdir, attrs, attr_count, NULL, 0); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); @@ -5671,17 +5666,17 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, } // compact into new mdir tags >= split_id - err = lfsr_mdir_compact_(lfs, &msibling_, mid, split_id, -1, + err = lfsr_mdir_compact_(lfs, &msibling_, mbid, split_id, -1, mdir, attrs, attr_count, NULL, 0); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); return err; } - LFS_DEBUG("Splitting mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"} " + LFS_DEBUG("Splitting mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"} " "-> 0x{%"PRIx32",%"PRIx32"}" ", 0x{%"PRIx32",%"PRIx32"}", - mdir->mid, + mdir->mid.bid, mdir->m.rbyd.block, mdir->m.redund_block, mdir_.m.rbyd.block, mdir_.m.redund_block, msibling_.m.rbyd.block, msibling_.m.redund_block); @@ -5691,26 +5686,26 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // both siblings reduced to zero if (mdir_.m.rbyd.weight == 0 && msibling_.m.rbyd.weight == 0) { - LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", - mdir_.mid, + LFS_DEBUG("Dropping mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"}", + mdir_.mid.bid, mdir_.m.rbyd.block, mdir_.m.redund_block); - LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", - msibling_.mid, + LFS_DEBUG("Dropping mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"}", + msibling_.mid.bid, msibling_.m.rbyd.block, msibling_.m.redund_block); // mark as dropped mdir_.m.rbyd.trunk = 0; msibling_.m.rbyd.trunk = 0; // update our mtree - int err = lfsr_btree_pop(lfs, &mtree_, mid); + int err = lfsr_btree_pop(lfs, &mtree_, mbid); if (err) { return err; } // one sibling reduced to zero } else if (mdir_.m.rbyd.weight == 0) { - LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", - mdir_.mid, + LFS_DEBUG("Dropping mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"}", + mdir_.mid.bid, mdir_.m.rbyd.block, mdir_.m.redund_block); // mark as dropped @@ -5723,7 +5718,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, return d; } - int err = lfsr_btree_set(lfs, &mtree_, mid, LFSR_TAG_MDIR, 1, + int err = lfsr_btree_set(lfs, &mtree_, mbid, LFSR_TAG_MDIR, 1, LFSR_DATA_BUF(buf, d)); if (err) { return err; @@ -5731,8 +5726,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // other sibling reduced to zero } else if (msibling_.m.rbyd.weight == 0) { - LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", - msibling_.mid, + LFS_DEBUG("Dropping mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"}", + msibling_.mid.bid, msibling_.m.rbyd.block, msibling_.m.redund_block); // mark as dropped @@ -5745,7 +5740,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, return d; } - int err = lfsr_btree_set(lfs, &mtree_, mid, LFSR_TAG_MDIR, 1, + int err = lfsr_btree_set(lfs, &mtree_, mbid, LFSR_TAG_MDIR, 1, LFSR_DATA_BUF(buf, d)); if (err) { return err; @@ -5755,7 +5750,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, } else { // adjust our sibling's mid, do this here in case other sibling // was dropped - msibling_.mid += 1; + msibling_.mid.bid += 1; // update out mtree @@ -5783,7 +5778,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, return d2; } - err = lfsr_btree_split(lfs, &mtree_, mid, + err = lfsr_btree_split(lfs, &mtree_, mbid, (lfsr_tag_suptype(stag) == LFSR_TAG_NAME ? sdata : LFSR_DATA_NULL), @@ -5797,16 +5792,16 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, dirtymtree = true; // mdir reduced to zero? need to drop? - } else if (mdir->mid != -1 && mdir_.m.rbyd.weight == 0) { - LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", - mdir->mid, + } else if (mdir->mid.bid != -1 && mdir_.m.rbyd.weight == 0) { + LFS_DEBUG("Dropping mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"}", + mdir->mid.bid, mdir->m.rbyd.block, mdir->m.redund_block); // mark as dropped mdir_.m.rbyd.trunk = 0; // update our mtree - int err = lfsr_btree_pop(lfs, &mtree_, mdir->mid); + int err = lfsr_btree_pop(lfs, &mtree_, mdir->mid.bid); if (err) { return err; } @@ -5816,16 +5811,16 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // need to relocate? } else if (lfsr_mdir_cmp(mdir, &mdir_) != 0) { // relocate mroot - if (mdir->mid == -1) { + if (mdir->mid.bid == -1) { // if we're relocating our root, just mark the root as dirty // and let our dirtymroot code handle this dirtymroot = true; // relocate a normal mdir } else { - LFS_DEBUG("Relocating mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"} " + LFS_DEBUG("Relocating mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"} " "-> 0x{%"PRIx32",%"PRIx32"}", - mdir->mid, + mdir->mid.bid, mdir->m.rbyd.block, mdir->m.redund_block, mdir_.m.rbyd.block, mdir_.m.redund_block); @@ -5836,7 +5831,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, return d; } - int err = lfsr_btree_set(lfs, &mtree_, mdir->mid, LFSR_TAG_MDIR, 1, + int err = lfsr_btree_set(lfs, &mtree_, + mdir->mid.bid, LFSR_TAG_MDIR, 1, LFSR_DATA_BUF(buf, d)); if (err) { return err; @@ -5874,32 +5870,32 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // fix our grm for (uint8_t j = 0; j < 2; j++) { - if (grm->rms[j].mid == mdir->mid) { - LFS_ASSERT(grm->rms[j].rid + if (grm->mids[j].bid == mdir->mid.bid) { + LFS_ASSERT(grm->mids[j].rid <= (lfs_ssize_t)mdir->m.rbyd.weight); // TODO do we need this if we allow mid=0 => mroot when // inlined? // update mid if we are uninlining - grm->rms[j].mid = lfs_smax32(grm->rms[j].mid, 0); + grm->mids[j].bid = lfs_smax32(grm->mids[j].bid, 0); - if (grm->rms[j].rid >= (lfs_ssize_t)mdir_.m.rbyd.weight) { - grm->rms[j].mid += 1; - grm->rms[j].rid -= mdir_.m.rbyd.weight; + if (grm->mids[j].rid >= (lfs_ssize_t)mdir_.m.rbyd.weight) { + grm->mids[j].bid += 1; + grm->mids[j].rid -= mdir_.m.rbyd.weight; } // update mid if we had a split or drop - } else if (grm->rms[j].mid > mdir->mid + } else if (grm->mids[j].bid > mdir->mid.bid && lfsr_btree_weight(&mtree_) != lfsr_mtree_weight(lfs)) { - grm->rms[j].mid += lfsr_btree_weight(&mtree_) + grm->mids[j].bid += lfsr_btree_weight(&mtree_) - lfsr_mtree_weight(lfs); } // TODO this is a big cludge, support for mid=0 when inlined? // adjust mid if mtree is inlined if (lfsr_btree_weight(&mtree_) == 0) { - LFS_ASSERT(grm->rms[j].mid <= 0); - if (grm->rms[j].mid == 0) { - grm->rms[j].mid = -1; + LFS_ASSERT(grm->mids[j].bid <= 0); + if (grm->mids[j].bid == 0) { + grm->mids[j].bid = -1; } } } @@ -5920,7 +5916,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // need to update mtree? if (dirtymtree) { - LFS_ASSERT(mdir_.mid != -1); + LFS_ASSERT(mdir_.mid.bid != -1); // commit mtree lfsr_tag_t tag; @@ -6064,10 +6060,11 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, for (lfs_size_t i = 0; i < attr_count; i++) { // TODO clean this up a bit? // adjust opened mdirs? - if (opened_mdir->mid == mdir->mid - && opened_mdir->rid >= attrs[i].id) { + if (opened_mdir->mid.bid == mdir->mid.bid + && opened_mdir->mid.rid >= attrs[i].id) { // removed? - if (opened_mdir->rid + attrs[i].delta < attrs[i].id) { + if (opened_mdir->mid.rid + < attrs[i].id - attrs[i].delta) { // normal mdirs mark as dropped if (j == 0) { opened_mdir->m.rbyd.trunk = 0; @@ -6075,9 +6072,9 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, } // for dir's second mdir (the position mdir), move // on to the next rid - opened_mdir->rid = attrs[i].id; + opened_mdir->mid.rid = attrs[i].id; } else { - opened_mdir->rid += attrs[i].delta; + opened_mdir->mid.rid += attrs[i].delta; // adjust dir position? if (type == LFS_TYPE_DIR && j == 0) { ((lfsr_dir_t*)opened)->pos -= attrs[i].delta; @@ -6085,7 +6082,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, ((lfsr_dir_t*)opened)->pos += attrs[i].delta; } } - } else if (opened_mdir->mid > mdir->mid) { + } else if (opened_mdir->mid.bid > mdir->mid.bid) { // adjust dir position? if (type == LFS_TYPE_DIR && j == 0) { ((lfsr_dir_t*)opened)->pos -= attrs[i].delta; @@ -6096,21 +6093,21 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, } // update any opened mdirs if we had a split or drop - if (opened_mdir->mid == mdir->mid) { + if (opened_mdir->mid.bid == mdir->mid.bid) { if (!lfsr_mdir_isdropped(&msibling_) - && opened_mdir->rid + && opened_mdir->mid.rid >= (lfs_ssize_t)mdir_.m.rbyd.weight) { LFS_ASSERT(lfsr_btree_weight(&mtree_) != lfsr_mtree_weight(lfs)); - opened_mdir->mid = msibling_.mid; - opened_mdir->rid -= mdir_.m.rbyd.weight; + opened_mdir->mid.bid = msibling_.mid.bid; + opened_mdir->mid.rid -= mdir_.m.rbyd.weight; opened_mdir->m = msibling_.m; } else { - opened_mdir->mid = mdir_.mid; + opened_mdir->mid.bid = mdir_.mid.bid; opened_mdir->m = mdir_.m; } - } else if (opened_mdir->mid > mdir->mid) { - opened_mdir->mid += lfsr_btree_weight(&mtree_) + } else if (opened_mdir->mid.bid > mdir->mid.bid) { + opened_mdir->mid.bid += lfsr_btree_weight(&mtree_) - lfsr_mtree_weight(lfs); } } @@ -6119,14 +6116,14 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, } // update mdir to follow requested rid - LFS_ASSERT(mdir->rid <= (lfs_ssize_t)mdir->m.rbyd.weight); - if (mdir->mid < 0 && mdir->rid < 0) { + LFS_ASSERT(mdir->mid.rid <= (lfs_ssize_t)mdir->m.rbyd.weight); + if (mdir->mid.bid == -1 && mdir->mid.rid == -1) { mdir->m = mroot_.m; } else if (!lfsr_mdir_isdropped(&msibling_) - && mdir->rid >= (lfs_ssize_t)mdir_.m.rbyd.weight) { + && mdir->mid.rid >= (lfs_ssize_t)mdir_.m.rbyd.weight) { LFS_ASSERT(lfsr_btree_weight(&mtree_) != lfsr_mtree_weight(lfs)); - mdir->mid = msibling_.mid; - mdir->rid -= mdir_.m.rbyd.weight; + mdir->mid.bid = msibling_.mid.bid; + mdir->mid.rid -= mdir_.m.rbyd.weight; mdir->m = msibling_.m; } else { mdir->m = mdir_.m; @@ -6170,12 +6167,12 @@ static int lfsr_mtree_dnamelookup(lfs_t *lfs, // lookup dname in actual mtree } else { - lfs_size_t mid; + lfs_size_t bid; lfsr_tag_t tag; lfsr_data_t data; int err = lfsr_btree_dnamelookup(lfs, &lfs->mtree, did, name, name_size, - &mid, &tag, NULL, &data); + &bid, &tag, NULL, &data); if (err) { return err; } @@ -6189,20 +6186,25 @@ static int lfsr_mtree_dnamelookup(lfs_t *lfs, } // fetch mdir - err = lfsr_mdir_fetch(lfs, &mdir, mptr, mid, -1); + err = lfsr_mdir_fetch(lfs, &mdir, mptr, LFSR_MID(bid, -1)); if (err) { return err; } } + // and finally lookup dname in our mdir + lfs_ssize_t rid; + int err = lfsr_mdir_dnamelookup(lfs, &mdir, + did, name, name_size, + &rid, tag_, data_); + + // update mdir weith best place to insert even if we fail + mdir.mid.rid = rid; if (mdir_) { *mdir_ = mdir; } - // and finally lookup dname in our mdir - return lfsr_mdir_dnamelookup(lfs, &mdir, - did, name, name_size, - (mdir_ ? &mdir_->rid : NULL), tag_, data_); + return err; } @@ -6221,7 +6223,7 @@ static int lfsr_mtree_pathlookup(lfs_t *lfs, const char *path, lfsr_mdir_t *mdir_, lfsr_tag_t *tag_, lfs_size_t *did_, const char **name_, lfs_size_t *name_size_) { // setup root - lfsr_mdir_t mdir = {.rid=-1}; + lfsr_mdir_t mdir = {.mid.rid=-1}; lfsr_tag_t tag = LFSR_TAG_DIR; lfs_size_t did = LFSR_DID_ROOT; @@ -6275,7 +6277,7 @@ static int lfsr_mtree_pathlookup(lfs_t *lfs, const char *path, if (name[0] == '\0') { // generally we don't allow operations that change our root, // report root as inval, but let upper layers intercept this - if (mdir.rid == -1) { + if (mdir.mid.rid == -1) { return LFS_ERR_INVAL; } return 0; @@ -6287,9 +6289,9 @@ static int lfsr_mtree_pathlookup(lfs_t *lfs, const char *path, } // read the next did from the mdir if this is not the root - if (mdir.rid != -1) { + if (mdir.mid.rid != -1) { lfsr_data_t data; - int err = lfsr_mdir_lookup(lfs, &mdir, mdir.rid, LFSR_TAG_DID, + int err = lfsr_mdir_lookup(lfs, &mdir, mdir.mid.rid, LFSR_TAG_DID, NULL, &data); if (err) { return err; @@ -6368,7 +6370,7 @@ enum { static int lfsr_mtree_traversal_next(lfs_t *lfs, lfsr_mtree_traversal_t *traversal, - lfs_size_t *mid_, lfsr_tag_t *tag_, lfsr_data_t *data_) { + lfsr_mid_t *mid_, lfsr_tag_t *tag_, lfsr_data_t *data_) { // new traversal? start with 0x{0,1} // // note we make sure to include fake mroots! @@ -6376,13 +6378,13 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs, if (traversal->mdir.m.rbyd.trunk == 0) { // fetch the first mroot 0x{0,1} int err = lfsr_mdir_fetch(lfs, &traversal->mdir, - LFSR_MPTR_MROOTANCHOR, -1, -1); + LFSR_MPTR_MROOTANCHOR, LFSR_MID(-1, -1)); if (err) { return err; } if (mid_) { - *mid_ = -1; + *mid_ = LFSR_MID(-1, -1); } if (tag_) { *tag_ = LFSR_TAG_MDIR; @@ -6393,7 +6395,7 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs, goto cycle_detect; // check for mroot/mtree/mdir - } else if (traversal->mdir.mid == -1) { + } else if (traversal->mdir.mid.bid == -1) { // lookup mroot, if we find one this is a fake mroot lfsr_tag_t tag; lfsr_data_t data; @@ -6412,13 +6414,14 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs, return d; } - int err = lfsr_mdir_fetch(lfs, &traversal->mdir, mptr, -1, -1); + int err = lfsr_mdir_fetch(lfs, &traversal->mdir, + mptr, LFSR_MID(-1, -1)); if (err) { return err; } if (mid_) { - *mid_ = -1; + *mid_ = LFSR_MID(-1, -1); } if (tag_) { *tag_ = LFSR_TAG_MDIR; @@ -6457,12 +6460,12 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs, } // traverse through the mtree - lfs_size_t mid; + lfs_size_t bid; lfsr_tag_t tag; lfsr_data_t data; int err = lfsr_btree_traversal_next( lfs, &lfs->mtree, &traversal->mtraversal, - &mid, &tag, NULL, &data); + &bid, &tag, NULL, &data); if (err) { return err; } @@ -6509,10 +6512,10 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs, // still update our mdir mid so we don't get stuck in a loop // traversing mroots - traversal->mdir.mid = mid; + traversal->mdir.mid.bid = bid; if (mid_) { - *mid_ = mid; + *mid_ = LFSR_MID(bid, -1); } if (tag_) { *tag_ = tag; @@ -6530,13 +6533,14 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs, return d; } - int err = lfsr_mdir_fetch(lfs, &traversal->mdir, mptr, mid, -1); + int err = lfsr_mdir_fetch(lfs, &traversal->mdir, + mptr, LFSR_MID(bid, -1)); if (err) { return err; } if (mid_) { - *mid_ = mid; + *mid_ = LFSR_MID(bid, -1); } if (tag_) { *tag_ = tag; @@ -6590,12 +6594,13 @@ cycle_detect:; // - 32-bit block_size => 5 byte leb128 (worst case) // - 32-bit block_count => 5 byte leb128 (worst case) // - 7-bit utag_limit => 1 byte leb128 (worst case) +// - 16-bit mtree_limit => 3 byte leb128 (worst case) // - 32-bit attr_limit => 5 byte leb128 (worst case) // - 32-bit name_limit => 5 byte leb128 (worst case) // - 32-bit file_limit => 5 byte leb128 (worst case) -// => 30 bytes total +// => 33 bytes total // -#define LFSR_SUPERCONFIG_DSIZE (1+1+1+1+5+5+1+5+5+5) +#define LFSR_SUPERCONFIG_DSIZE (1+1+1+1+5+5+1+3+5+5+5) static lfs_ssize_t lfsr_superconfig_todisk(lfs_t *lfs, uint8_t buffer[static LFSR_SUPERCONFIG_DSIZE]) { @@ -6632,6 +6637,13 @@ static lfs_ssize_t lfsr_superconfig_todisk(lfs_t *lfs, buffer[d] = 0x7f; d += 1; + // on-disk mtree limit + d_ = lfs_toleb128(0x7fff, &buffer[d], 3); + if (d_ < 0) { + return d_; + } + d += d_; + // on-disk attr limit d_ = lfs_toleb128(0x7fffffff, &buffer[d], 5); if (d_ < 0) { @@ -6695,7 +6707,7 @@ static int lfsr_mountinited(lfs_t *lfs) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data.buf.buffer; // found an mroot? - if (mdir->mid == -1) { + if (mdir->mid.bid == -1) { // has magic string? lfsr_data_t data; err = lfsr_mdir_lookup(lfs, mdir, -1, LFSR_TAG_SUPERMAGIC, @@ -6871,6 +6883,28 @@ static int lfsr_mountinited(lfs_t *lfs) { return LFS_ERR_INVAL; } + // check the on-disk mtree limit + // TODO actually use this + uint32_t mtree_limit; + d_ = lfsr_data_readleb128(lfs, data, d, &mtree_limit); + // treat any leb128 overflows as out-of-range values + if (d_ < 0 && d_ != LFS_ERR_CORRUPT) { + return d_; + } + if (d_ != LFS_ERR_CORRUPT) { + d += d_; + } + + if (d_ == LFS_ERR_CORRUPT || mtree_limit != 0x7fff) { + LFS_ERROR("Incompatible mdir limit 0x%"PRIx32 + " (> 0x%"PRIx32")", + (d_ == LFS_ERR_CORRUPT + ? (uint32_t)-1 + : mtree_limit), + 0x7fff); + return LFS_ERR_INVAL; + } + // check the on-disk attr limit // TODO actually use this uint32_t attr_limit; @@ -6959,11 +6993,11 @@ static int lfsr_mountinited(lfs_t *lfs) { } if (lfsr_grm_hasrm(&lfs->grm)) { - LFS_DEBUG("Found pending grm %"PRId32".%"PRId32" %"PRId32".%"PRId32, - lfs->grm.rms[0].mid, - lfs->grm.rms[0].rid, - lfs->grm.rms[1].mid, - lfs->grm.rms[1].rid); + LFS_DEBUG("Found pending grm %"PRId16".%"PRId16" %"PRId16".%"PRId16, + lfs->grm.mids[0].bid, + lfs->grm.mids[0].rid, + lfs->grm.mids[1].bid, + lfs->grm.mids[1].rid); } return 0; @@ -7189,7 +7223,7 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) { err = lfsr_mtree_pathlookup(lfs, path, &parent.mdir, NULL, &parent_did, &name, &name_size); - if (err && (err != LFS_ERR_NOENT || parent.mdir.rid == -1)) { + if (err && (err != LFS_ERR_NOENT || parent.mdir.mid.rid == -1)) { return err; } @@ -7258,7 +7292,7 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) { // parent's mdir/rid. We can catch this by tracking our parent // as "opened" temporarily // TODO is this the best workaround for rid update issues? - parent.mdir.rid -= 1; + parent.mdir.mid.rid -= 1; lfsr_mdir_addopened(lfs, LFS_TYPE_REG, &parent); // Conveniently, we just found where our dstart should go. The dstart @@ -7268,26 +7302,26 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) { // lose power before writing the entry in our parent // err = lfsr_mdir_commit(lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR_DNAME(mdir.rid, DSTART, +1, did, NULL, 0), - LFSR_ATTR_GRM(-1, GRM, 0, &((lfsr_grm_t){.rms={ - {.mid=mdir.mid, .rid=mdir.rid}, - {.mid=-1, .rid=-1}}})))); + LFSR_ATTR_DNAME(mdir.mid.rid, DSTART, +1, did, NULL, 0), + LFSR_ATTR_GRM(-1, GRM, 0, &((lfsr_grm_t){{ + mdir.mid, + LFSR_MID(-1, -1)}})))); if (err) { goto failed_with_parent; } lfsr_mdir_removeopened(lfs, LFS_TYPE_REG, &parent); - parent.mdir.rid += 1; + parent.mdir.mid.rid += 1; // commit our new directory into our parent, zeroing out our grm // in the process err = lfsr_mdir_commit(lfs, &parent.mdir, LFSR_ATTRS( - LFSR_ATTR_DNAME(parent.mdir.rid, DIR, +1, + LFSR_ATTR_DNAME(parent.mdir.mid.rid, DIR, +1, parent_did, name, name_size), - LFSR_ATTR_LEB128(parent.mdir.rid, DID, 0, did), - LFSR_ATTR_GRM(-1, GRM, 0, &((lfsr_grm_t){.rms={ - {.mid=-1, .rid=-1}, - {.mid=-1, .rid=-1}}})))); + LFSR_ATTR_LEB128(parent.mdir.mid.rid, DID, 0, did), + LFSR_ATTR_GRM(-1, GRM, 0, &((lfsr_grm_t){{ + LFSR_MID(-1, -1), + LFSR_MID(-1, -1)}})))); if (err) { return err; } @@ -7322,7 +7356,7 @@ int lfsr_remove(lfs_t *lfs, const char *path) { if (tag == LFSR_TAG_DIR) { // first lets figure out the did lfsr_data_t data; - int err = lfsr_mdir_lookup(lfs, &mdir, mdir.rid, LFSR_TAG_DID, + int err = lfsr_mdir_lookup(lfs, &mdir, mdir.mid.rid, LFSR_TAG_DID, NULL, &data); if (err) { return err; @@ -7344,7 +7378,7 @@ int lfsr_remove(lfs_t *lfs, const char *path) { } // create a grm to remove the dstart entry - lfsr_grm_pushrm(&grm, mdir_.mid, mdir_.rid); + lfsr_grm_pushrm(&grm, mdir_.mid); // check that the directory is empty err = lfsr_mtree_seek(lfs, &mdir_, 1); @@ -7354,7 +7388,8 @@ int lfsr_remove(lfs_t *lfs, const char *path) { if (err != LFS_ERR_NOENT) { lfsr_tag_t tag_; - err = lfsr_mdir_lookup(lfs, &mdir_, mdir_.rid, LFSR_TAG_WIDENAME, + err = lfsr_mdir_lookup(lfs, &mdir_, + mdir_.mid.rid, LFSR_TAG_WIDENAME, &tag_, NULL); if (err) { return err; @@ -7366,14 +7401,15 @@ int lfsr_remove(lfs_t *lfs, const char *path) { } // adjust rid if grm is on the same mdir as our dir - if (grm.rms[0].mid == mdir.mid && grm.rms[0].rid > mdir.rid) { - grm.rms[0].rid -= 1; + if (grm.mids[0].bid == mdir.mid.bid + && grm.mids[0].rid > mdir.mid.rid) { + grm.mids[0].rid -= 1; } } // remove the metadata entry err = lfsr_mdir_commit(lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, UNR, -1, NULL, 0), + LFSR_ATTR(mdir.mid.rid, UNR, -1, NULL, 0), LFSR_ATTR_GRM(-1, GRM, 0, &grm))); if (err) { return err; @@ -7403,7 +7439,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { // mark old entry for removal with a grm lfsr_grm_t grm = lfs->grm; - lfsr_grm_pushrm(&grm, old_mdir.mid, old_mdir.rid); + lfsr_grm_pushrm(&grm, old_mdir.mid); // lookup new entry lfsr_mdir_t new_mdir; @@ -7414,7 +7450,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { err = lfsr_mtree_pathlookup(lfs, new_path, &new_mdir, &new_tag, &new_did, &new_name, &new_name_size); - if (err && (err != LFS_ERR_NOENT || new_mdir.rid == -1)) { + if (err && (err != LFS_ERR_NOENT || new_mdir.mid.rid == -1)) { return err; } bool exists = (err != LFS_ERR_NOENT); @@ -7427,8 +7463,9 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { } // adjust old rid if grm is on the same mdir as new rid - if (grm.rms[0].mid == new_mdir.mid && grm.rms[0].rid >= new_mdir.rid) { - grm.rms[0].rid += 1; + if (grm.mids[0].bid == new_mdir.mid.bid + && grm.mids[0].rid >= new_mdir.mid.rid) { + grm.mids[0].rid += 1; } } else { @@ -7439,7 +7476,8 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { // TODO is it? is this check necessary? // renaming to ourself is a noop - if (old_mdir.mid == new_mdir.mid && old_mdir.rid == new_mdir.rid) { + if (old_mdir.mid.bid == new_mdir.mid.bid + && old_mdir.mid.rid == new_mdir.mid.rid) { return 0; } @@ -7450,7 +7488,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { // first lets figure out the did lfsr_data_t data; int err = lfsr_mdir_lookup(lfs, &new_mdir, - new_mdir.rid, LFSR_TAG_DID, + new_mdir.mid.rid, LFSR_TAG_DID, NULL, &data); if (err) { return err; @@ -7472,7 +7510,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { } // create a grm to remove the dstart entry - lfsr_grm_pushrm(&grm, mdir_.mid, mdir_.rid); + lfsr_grm_pushrm(&grm, mdir_.mid); // check that the directory is empty err = lfsr_mtree_seek(lfs, &mdir_, 1); @@ -7483,7 +7521,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { if (err != LFS_ERR_NOENT) { lfsr_tag_t tag_; err = lfsr_mdir_lookup(lfs, &mdir_, - mdir_.rid, LFSR_TAG_WIDENAME, + mdir_.mid.rid, LFSR_TAG_WIDENAME, &tag_, NULL); if (err) { return err; @@ -7500,12 +7538,11 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { // new rid, while also marking the old rid for removal err = lfsr_mdir_commit(lfs, &new_mdir, LFSR_ATTRS( (exists - ? LFSR_ATTR(new_mdir.rid, UNR, -1, NULL, 0) + ? LFSR_ATTR(new_mdir.mid.rid, UNR, -1, NULL, 0) : LFSR_ATTR_NOOP), - LFSR_ATTR_DNAME_(new_mdir.rid, old_tag, +1, + LFSR_ATTR_DNAME_(new_mdir.mid.rid, old_tag, +1, new_did, new_name, new_name_size), - LFSR_ATTR_MOVE(new_mdir.rid, MOVE, 0, - &old_mdir.m.rbyd, old_mdir.rid), + LFSR_ATTR_MOVE(new_mdir.mid.rid, MOVE, 0, &old_mdir), LFSR_ATTR_GRM(-1, GRM, 0, &grm))); // we need to clean up any pending grms, fortunately we can leave @@ -7568,7 +7605,7 @@ int lfsr_dir_open(lfs_t *lfs, lfsr_dir_t *dir, const char *path) { dir->did = 0; } else { lfsr_data_t data; - int err = lfsr_mdir_lookup(lfs, &mdir, mdir.rid, LFSR_TAG_DID, + int err = lfsr_mdir_lookup(lfs, &mdir, mdir.mid.rid, LFSR_TAG_DID, NULL, &data); if (err) { return err; @@ -7631,7 +7668,7 @@ int lfsr_dir_read(lfs_t *lfs, lfsr_dir_t *dir, struct lfs_info *info) { lfsr_tag_t tag; lfsr_data_t data; err = lfsr_mdir_lookup(lfs, &dir->pos_mdir, - dir->pos_mdir.rid, LFSR_TAG_WIDENAME, + dir->pos_mdir.mid.rid, LFSR_TAG_WIDENAME, &tag, &data); if (err) { return err; @@ -7727,10 +7764,8 @@ static int lfsr_fs_fixgrm(lfs_t *lfs) { while (lfsr_grm_hasrm(&lfs->grm)) { // find our mdir lfsr_mdir_t mdir; - LFS_ASSERT(lfs->grm.rms[0].mid < (lfs_ssize_t)lfsr_mtree_weight(lfs)); - int err = lfsr_mtree_lookup(lfs, - lfs->grm.rms[0].mid, lfs->grm.rms[0].rid, - &mdir); + LFS_ASSERT(lfs->grm.mids[0].bid < (lfs_ssize_t)lfsr_mtree_weight(lfs)); + int err = lfsr_mtree_lookup(lfs, lfs->grm.mids[0], &mdir); if (err) { return err; } @@ -7740,15 +7775,16 @@ static int lfsr_fs_fixgrm(lfs_t *lfs) { lfsr_grm_poprm(&grm); // make sure to adjust any remaining grms - if (grm.rms[0].mid == mdir.mid && grm.rms[0].rid >= mdir.rid) { - LFS_ASSERT(grm.rms[0].rid != mdir.rid); - grm.rms[0].rid -= 1; + if (grm.mids[0].bid == mdir.mid.bid + && grm.mids[0].rid >= mdir.mid.rid) { + LFS_ASSERT(grm.mids[0].rid != mdir.mid.rid); + grm.mids[0].rid -= 1; } // remove the rid while also updating our grm - LFS_ASSERT(lfs->grm.rms[0].rid < (lfs_ssize_t)mdir.m.rbyd.weight); + LFS_ASSERT(lfs->grm.mids[0].rid < (lfs_ssize_t)mdir.m.rbyd.weight); err = lfsr_mdir_commit(lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, UNR, -1, NULL, 0), + LFSR_ATTR(mdir.mid.rid, UNR, -1, NULL, 0), LFSR_ATTR_GRM(-1, GRM, 0, &grm))); } @@ -7761,11 +7797,11 @@ static int lfsr_fs_preparemutation(lfs_t *lfs) { // fix pending grms if (lfsr_grm_hasrm(&lfs->grm)) { - LFS_DEBUG("Fixing grm %"PRId32".%"PRId32" %"PRId32".%"PRId32, - lfs->grm.rms[0].mid, - lfs->grm.rms[0].rid, - lfs->grm.rms[1].mid, - lfs->grm.rms[1].rid); + LFS_DEBUG("Fixing grm %"PRId16".%"PRId16" %"PRId16".%"PRId16, + lfs->grm.mids[0].bid, + lfs->grm.mids[0].rid, + lfs->grm.mids[1].bid, + lfs->grm.mids[1].rid); int err = lfsr_fs_fixgrm(lfs); if (err) { diff --git a/lfs.h b/lfs.h index 27404093..37357606 100644 --- a/lfs.h +++ b/lfs.h @@ -47,6 +47,11 @@ typedef uint32_t lfs_block_t; typedef uint16_t lfsr_tag_t; typedef int16_t lfsr_stag_t; +typedef uint16_t lfsr_mbid_t; +typedef int16_t lfsr_smbid_t; +typedef uint16_t lfsr_mrid_t; +typedef int16_t lfsr_smrid_t; + // Maximum name size in bytes, may be redefined to reduce the size of the // info struct. Limited to <= 1022. Stored in superblock and must be // respected by other littlefs drivers. @@ -368,12 +373,13 @@ typedef union lfsr_btree { } inlined; } lfsr_btree_t; +typedef struct lfsr_mid { + lfsr_smbid_t bid; + lfsr_smrid_t rid; +} lfsr_mid_t; + typedef struct lfsr_mdir { - // -2 => deleted - // -1 => mroot - // >=0 => bid in the mtree - lfs_ssize_t mid; - lfs_ssize_t rid; + lfsr_mid_t mid; struct { lfsr_rbyd_t rbyd; lfs_block_t redund_block; @@ -387,17 +393,14 @@ typedef struct lfsr_openedmdir { // space for: // - type - 1 leb128 - 1 byte (worst case) -// - mid0 - 1 leb128 - 5 bytes (worst case) -// - rid0 - 1 leb128 - 5 bytes (worst case) -// - mid1 - 1 leb128 - 5 bytes (worst case) -// - rid1 - 1 leb128 - 5 bytes (worst case) -#define LFSR_GRM_DSIZE (1+5+5+5+5) +// - mid0 - 1 leb128 - 3 bytes (worst case) +// - rid0 - 1 leb128 - 3 bytes (worst case) +// - mid1 - 1 leb128 - 3 bytes (worst case) +// - rid1 - 1 leb128 - 3 bytes (worst case) +#define LFSR_GRM_DSIZE (1+3+3+3+3) typedef struct lfsr_grm { - struct { - lfs_ssize_t mid; - lfs_ssize_t rid; - } rms[2]; + lfsr_mid_t mids[2]; } lfsr_grm_t; diff --git a/tests/t3_mtree.toml b/tests/t3_mtree.toml index 45c0f93a..1ae990fc 100644 --- a/tests/t3_mtree.toml +++ b/tests/t3_mtree.toml @@ -176,7 +176,7 @@ code = ''' // assert that our entry is still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -200,7 +200,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -245,13 +245,13 @@ code = ''' // assert that our entries are still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -269,13 +269,13 @@ code = ''' assert(lfs.mroot.m.rbyd.weight == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -319,7 +319,7 @@ code = ''' // now add another large entry to the mdir, forcing a split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); @@ -341,13 +341,13 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[1 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -369,13 +369,13 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[1 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -402,9 +402,9 @@ code = ''' // create entries lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(lfsr_mtree_weight(&lfs)-1, -1), &mdir) => 0; - mdir.rid = 0; + mdir.mid.rid = 0; for (lfs_size_t i = 0; i < N; i++) { // force a compaction? if (FORCE_COMPACTION) { @@ -413,14 +413,14 @@ code = ''' } lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; + LFSR_ATTR(mdir.mid.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); - mdir.rid += 1; + mdir.mid.rid += 1; } // try looking up each entry @@ -429,12 +429,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -454,12 +454,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -498,9 +498,9 @@ code = ''' : (lfs_ssize_t)(TEST_PRNG(&prng) % lfsr_mtree_weight(&lfs)); // fetch mdir lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // choose a pseudo-random rid - mdir.rid = TEST_PRNG(&prng) % (mdir.m.rbyd.weight+1); + mdir.mid.rid = TEST_PRNG(&prng) % (mdir.m.rbyd.weight+1); // force a compaction? if (FORCE_COMPACTION) { @@ -510,11 +510,11 @@ code = ''' // add to rbyd, potentially splitting the mdir lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; + LFSR_ATTR(mdir.mid.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; // make sure we can look up the new entry uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); @@ -528,12 +528,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -557,12 +557,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -615,7 +615,7 @@ code = ''' // remove the entry, forcing the mdir to be dropped lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( @@ -685,7 +685,7 @@ code = ''' // remove the entry, forcing the mdir to be dropped lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); // force mdir to compact while we're removing @@ -822,7 +822,7 @@ code = ''' // assert that one entry is still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -841,7 +841,7 @@ code = ''' assert(lfs.mroot.m.rbyd.weight == 0); // assert that one entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -890,7 +890,7 @@ code = ''' // assert that one entry is still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -909,7 +909,7 @@ code = ''' assert(lfs.mroot.m.rbyd.weight == 0); // assert that one entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -1005,7 +1005,7 @@ code = ''' // now add another large entry to the mdir, forcing a split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); @@ -1031,7 +1031,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that one entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -1055,7 +1055,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that one entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -1100,7 +1100,7 @@ code = ''' // now add another large entry to the mdir, forcing a split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); @@ -1126,7 +1126,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that one entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -1150,7 +1150,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that one entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -1195,7 +1195,7 @@ code = ''' // now add another large entry to the mdir, forcing a split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); @@ -1258,29 +1258,29 @@ code = ''' // create entries lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(lfsr_mtree_weight(&lfs)-1, -1), &mdir) => 0; - mdir.rid = 0; + mdir.mid.rid = 0; for (lfs_size_t i = 0; i < N; i++) { lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; + LFSR_ATTR(mdir.mid.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); - mdir.rid += 1; + mdir.mid.rid += 1; } // remove entries for (lfs_size_t i = 0; i < N - REMAINING; i++) { lfs_ssize_t mid = (lfsr_mtree_isinlined(&lfs) ? -1 : 0); lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // drop should make sure we never have empty mdirs - assert(mdir.mid == -1 || mdir.m.rbyd.weight > 0); + assert(mdir.mid.bid == -1 || mdir.m.rbyd.weight > 0); // force a compaction? if (FORCE_COMPACTION) { @@ -1298,12 +1298,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -1323,12 +1323,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -1358,19 +1358,19 @@ code = ''' for (lfs_size_t cycle = 0; cycle < CYCLES; cycle++) { // create entries lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(lfsr_mtree_weight(&lfs)-1, -1), &mdir) => 0; - mdir.rid = 0; + mdir.mid.rid = 0; for (lfs_size_t i = 0; i < N; i++) { lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; + LFSR_ATTR(mdir.mid.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); - mdir.rid += 1; + mdir.mid.rid += 1; } // try looking up each entry @@ -1379,12 +1379,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -1396,10 +1396,10 @@ code = ''' for (lfs_size_t i = 0; i < N; i++) { lfs_ssize_t mid = (lfsr_mtree_isinlined(&lfs) ? -1 : 0); lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // drop should make sure we never have empty mdirs - assert(mdir.mid == -1 || mdir.m.rbyd.weight > 0); + assert(mdir.mid.bid == -1 || mdir.m.rbyd.weight > 0); // force a compaction? if (FORCE_COMPACTION) { @@ -1454,11 +1454,11 @@ code = ''' : (lfs_ssize_t)(TEST_PRNG(&prng) % lfsr_mtree_weight(&lfs)); // fetch mdir lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // choose a pseudo-random rid - mdir.rid = TEST_PRNG(&prng) % (mdir.m.rbyd.weight+1); + mdir.mid.rid = TEST_PRNG(&prng) % (mdir.m.rbyd.weight+1); // choose to create or delete - uint8_t op = (lfs_size_t)mdir.rid == mdir.m.rbyd.weight + uint8_t op = (lfs_size_t)mdir.mid.rid == mdir.m.rbyd.weight ? 0 : TEST_PRNG(&prng) % 2; @@ -1472,12 +1472,12 @@ code = ''' if (op == 0) { // add to rbyd, potentially splitting the mdir lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, +1, + LFSR_ATTR(mdir.mid.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; // make sure we can look up the new entry uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); @@ -1486,7 +1486,7 @@ code = ''' // delete } else { lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, UNR, -1, NULL, 0))) => 0; + LFSR_ATTR(mdir.mid.rid, UNR, -1, NULL, 0))) => 0; count -= 1; } @@ -1499,16 +1499,16 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // drop should make sure we never have empty mdirs - assert(mdir.mid == -1 || mdir.m.rbyd.weight > 0); + assert(mdir.mid.bid == -1 || mdir.m.rbyd.weight > 0); - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -1532,16 +1532,16 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // drop should make sure we never have empty mdirs - assert(mdir.mid == -1 || mdir.m.rbyd.weight > 0); + assert(mdir.mid.bid == -1 || mdir.m.rbyd.weight > 0); - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -1597,7 +1597,7 @@ code = ''' // force mdir to compact twice, this should relocate lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_t old_mdir = mdir; @@ -1618,7 +1618,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -1645,7 +1645,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -1692,7 +1692,7 @@ code = ''' // force mdir to compact twice, this should relocate lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_t old_mdir = mdir; @@ -1708,13 +1708,13 @@ code = ''' assert(lfsr_mdir_cmp(&old_mdir, &mdir) != 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[2 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -1735,13 +1735,13 @@ code = ''' assert(lfsr_mdir_cmp(&old_mdir, &mdir) != 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[2 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -1787,7 +1787,7 @@ code = ''' // force mdir to compact twice, this should relocate lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_t old_mdir = mdir; @@ -1803,13 +1803,13 @@ code = ''' assert(lfsr_mdir_cmp(&old_mdir, &mdir) != 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -1830,13 +1830,13 @@ code = ''' assert(lfsr_mdir_cmp(&old_mdir, &mdir) != 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -2075,7 +2075,7 @@ code = ''' // force mdir to compact twice, this should relocate lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_t old_mdir = mdir; @@ -2099,7 +2099,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -2129,7 +2129,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -2181,7 +2181,7 @@ code = ''' // now add another large entry to the mdir, forcing a split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); @@ -2206,13 +2206,13 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[1 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -2238,13 +2238,13 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[1 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -2295,7 +2295,7 @@ code = ''' // remove the entry, forcing the mdir to be dropped lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( @@ -2388,7 +2388,7 @@ code = ''' // assert that our entry is still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -2415,7 +2415,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -2471,13 +2471,13 @@ code = ''' // assert that our entries are still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -2498,13 +2498,13 @@ code = ''' assert(lfsr_mdir_cmp(&old_mroot, &lfs.mroot) != 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -2542,11 +2542,11 @@ code = ''' : (lfs_ssize_t)(TEST_PRNG(&prng) % lfsr_mtree_weight(&lfs)); // fetch mdir lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // choose a pseudo-random rid - mdir.rid = TEST_PRNG(&prng) % (mdir.m.rbyd.weight+1); + mdir.mid.rid = TEST_PRNG(&prng) % (mdir.m.rbyd.weight+1); // choose to create or delete - uint8_t op = (lfs_size_t)mdir.rid == mdir.m.rbyd.weight + uint8_t op = (lfs_size_t)mdir.mid.rid == mdir.m.rbyd.weight ? 0 : TEST_PRNG(&prng) % 3; @@ -2560,12 +2560,12 @@ code = ''' if (op == 0) { // add to rbyd lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, +1, + LFSR_ATTR(mdir.mid.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; // make sure we can look up the new entry uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); @@ -2575,19 +2575,19 @@ code = ''' } else if (op == 1) { // update rbyd lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, 0, + LFSR_ATTR(mdir.mid.rid, INLINED, 0, &alphas[i % 26], 1))) => 0; // make sure we can look up the new entry uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); // delete } else { lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, UNR, -1, NULL, 0))) => 0; + LFSR_ATTR(mdir.mid.rid, UNR, -1, NULL, 0))) => 0; count -= 1; } @@ -2600,16 +2600,16 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // drop should make sure we never have empty mdirs - assert(mdir.mid == -1 || mdir.m.rbyd.weight > 0); + assert(mdir.mid.bid == -1 || mdir.m.rbyd.weight > 0); - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -2633,16 +2633,16 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // drop should make sure we never have empty mdirs - assert(mdir.mid == -1 || mdir.m.rbyd.weight > 0); + assert(mdir.mid.bid == -1 || mdir.m.rbyd.weight > 0); - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -2679,9 +2679,9 @@ code = ''' assert(lfsr_mtree_isinlined(&lfs)); lfsr_openedmdir_t left_neighbor = { - .mdir={.mid=-1, .rid=0, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 0), .m=lfs.mroot.m}}; lfsr_openedmdir_t right_neighbor = { - .mdir={.mid=-1, .rid=1, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 1), .m=lfs.mroot.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -2699,13 +2699,13 @@ code = ''' // assert that our neighbors were updated correctly assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(left_neighbor.mdir.mid == -1); - assert(left_neighbor.mdir.rid == 0); + assert(left_neighbor.mdir.mid.bid == -1); + assert(left_neighbor.mdir.mid.rid == 0); assert(memcmp(&left_neighbor.mdir.m, &lfs.mroot.m, sizeof(lfs.mroot.m)) == 0); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); - assert(right_neighbor.mdir.mid == -1); - assert(right_neighbor.mdir.rid == 2); + assert(right_neighbor.mdir.mid.bid == -1); + assert(right_neighbor.mdir.mid.rid == 2); assert(memcmp(&right_neighbor.mdir.m, &lfs.mroot.m, sizeof(lfs.mroot.m)) == 0); @@ -2734,9 +2734,9 @@ code = ''' assert(lfsr_mtree_isinlined(&lfs)); lfsr_openedmdir_t left_neighbor = { - .mdir={.mid=-1, .rid=0, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 0), .m=lfs.mroot.m}}; lfsr_openedmdir_t right_neighbor = { - .mdir={.mid=-1, .rid=1, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 1), .m=lfs.mroot.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -2750,8 +2750,8 @@ code = ''' // assert that our neighbors were updated correctly assert(lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); - assert(right_neighbor.mdir.mid == -1); - assert(right_neighbor.mdir.rid == 0); + assert(right_neighbor.mdir.mid.bid == -1); + assert(right_neighbor.mdir.mid.rid == 0); assert(memcmp(&right_neighbor.mdir.m, &lfs.mroot.m, sizeof(lfs.mroot.m)) == 0); @@ -2780,9 +2780,9 @@ code = ''' assert(lfsr_mtree_isinlined(&lfs)); lfsr_openedmdir_t left_neighbor = { - .mdir={.mid=-1, .rid=0, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 0), .m=lfs.mroot.m}}; lfsr_openedmdir_t right_neighbor = { - .mdir={.mid=-1, .rid=1, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 1), .m=lfs.mroot.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -2795,8 +2795,8 @@ code = ''' // assert that our neighbors were updated correctly assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(left_neighbor.mdir.mid == -1); - assert(left_neighbor.mdir.rid == 0); + assert(left_neighbor.mdir.mid.bid == -1); + assert(left_neighbor.mdir.mid.rid == 0); assert(memcmp(&left_neighbor.mdir.m, &lfs.mroot.m, sizeof(lfs.mroot.m)) == 0); assert(lfsr_mdir_isdropped(&right_neighbor.mdir)); @@ -2828,9 +2828,9 @@ code = ''' assert(lfsr_mtree_isinlined(&lfs)); lfsr_openedmdir_t left_neighbor = { - .mdir={.mid=-1, .rid=0, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 0), .m=lfs.mroot.m}}; lfsr_openedmdir_t right_neighbor = { - .mdir={.mid=-1, .rid=1, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 1), .m=lfs.mroot.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -2861,7 +2861,7 @@ code = ''' // assert that our entry is still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 2); lfsr_mdir_get(&lfs, &mdir, 1, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -2870,18 +2870,18 @@ code = ''' // note that our current implementation splits here, which is suboptimal // but saves on code size lfsr_mdir_t msibling; - lfsr_mtree_lookup(&lfs, 1, -1, &msibling) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &msibling) => 0; assert(msibling.m.rbyd.weight == 1); // assert that our neighbors were updated correctly assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(left_neighbor.mdir.mid == 0); - assert(left_neighbor.mdir.rid == 0); + assert(left_neighbor.mdir.mid.bid == 0); + assert(left_neighbor.mdir.mid.rid == 0); assert(memcmp(&left_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); - assert(right_neighbor.mdir.mid == 1); - assert(right_neighbor.mdir.rid == 0); + assert(right_neighbor.mdir.mid.bid == 1); + assert(right_neighbor.mdir.mid.rid == 0); assert(memcmp(&right_neighbor.mdir.m, &msibling.m, sizeof(msibling.m)) == 0); @@ -2912,9 +2912,9 @@ code = ''' assert(lfsr_mtree_isinlined(&lfs)); lfsr_openedmdir_t left_neighbor = { - .mdir={.mid=-1, .rid=0, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 0), .m=lfs.mroot.m}}; lfsr_openedmdir_t right_neighbor = { - .mdir={.mid=-1, .rid=1, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 1), .m=lfs.mroot.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -2939,14 +2939,14 @@ code = ''' // assert that our entries are still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 2); lfsr_mdir_get(&lfs, &mdir, 1, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[2 % 26], 1) == 0); lfsr_mdir_t msibling; - lfsr_mtree_lookup(&lfs, 1, -1, &msibling) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &msibling) => 0; assert(msibling.m.rbyd.weight == 2); lfsr_mdir_get(&lfs, &msibling, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -2954,13 +2954,13 @@ code = ''' // assert that our neighbors were updated correctly assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(left_neighbor.mdir.mid == 0); - assert(left_neighbor.mdir.rid == 0); + assert(left_neighbor.mdir.mid.bid == 0); + assert(left_neighbor.mdir.mid.rid == 0); assert(memcmp(&left_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); - assert(right_neighbor.mdir.mid == 1); - assert(right_neighbor.mdir.rid == 1); + assert(right_neighbor.mdir.mid.bid == 1); + assert(right_neighbor.mdir.mid.rid == 1); assert(memcmp(&right_neighbor.mdir.m, &msibling.m, sizeof(msibling.m)) == 0); @@ -3007,7 +3007,7 @@ code = ''' // note we do this after uninlining! this is because uninlining may // aggresively split the mtree if there are already neighbors in the mdir lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( @@ -3018,9 +3018,9 @@ code = ''' assert(mdir.m.rbyd.weight == 3); lfsr_openedmdir_t left_neighbor = { - .mdir={.mid=mdir.mid, .rid=0, .m=mdir.m}}; + .mdir={.mid=LFSR_MID(mdir.mid.bid, 0), .m=mdir.m}}; lfsr_openedmdir_t right_neighbor = { - .mdir={.mid=mdir.mid, .rid=2, .m=mdir.m}}; + .mdir={.mid=LFSR_MID(mdir.mid.bid, 2), .m=mdir.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -3044,14 +3044,14 @@ code = ''' assert(memcmp(buffer, &alphas[2 % 26], 1) == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 2); lfsr_mdir_get(&lfs, &mdir, 1, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[3 % 26], 1) == 0); lfsr_mdir_t msibling; - lfsr_mtree_lookup(&lfs, 1, -1, &msibling) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &msibling) => 0; assert(msibling.m.rbyd.weight == 2); lfsr_mdir_get(&lfs, &msibling, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -3059,13 +3059,13 @@ code = ''' // assert that our neighbors were updated correctly assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(left_neighbor.mdir.mid == 0); - assert(left_neighbor.mdir.rid == 0); + assert(left_neighbor.mdir.mid.bid == 0); + assert(left_neighbor.mdir.mid.rid == 0); assert(memcmp(&left_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); - assert(right_neighbor.mdir.mid == 1); - assert(right_neighbor.mdir.rid == 1); + assert(right_neighbor.mdir.mid.bid == 1); + assert(right_neighbor.mdir.mid.rid == 1); assert(memcmp(&right_neighbor.mdir.m, &msibling.m, sizeof(msibling.m)) == 0); @@ -3098,9 +3098,9 @@ code = ''' assert(lfsr_mtree_isinlined(&lfs)); lfsr_openedmdir_t left_neighbor = { - .mdir={.mid=-1, .rid=0, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 0), .m=lfs.mroot.m}}; lfsr_openedmdir_t right_neighbor = { - .mdir={.mid=-1, .rid=1, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 1), .m=lfs.mroot.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -3130,13 +3130,13 @@ code = ''' // assert that our neighbors were updated correctly assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(left_neighbor.mdir.mid == -1); - assert(left_neighbor.mdir.rid == 0); + assert(left_neighbor.mdir.mid.bid == -1); + assert(left_neighbor.mdir.mid.rid == 0); assert(memcmp(&left_neighbor.mdir.m, &lfs.mroot.m, sizeof(lfs.mroot.m)) == 0); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); - assert(right_neighbor.mdir.mid == -1); - assert(right_neighbor.mdir.rid == 1); + assert(right_neighbor.mdir.mid.bid == -1); + assert(right_neighbor.mdir.mid.rid == 1); assert(memcmp(&right_neighbor.mdir.m, &lfs.mroot.m, sizeof(lfs.mroot.m)) == 0); @@ -3185,7 +3185,7 @@ code = ''' // note we do this after uninlining! this is because uninlining may // aggresively split the mtree if there are already neighbors in the mdir lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( @@ -3196,9 +3196,9 @@ code = ''' assert(mdir.m.rbyd.weight == 3); lfsr_openedmdir_t left_neighbor = { - .mdir={.mid=mdir.mid, .rid=0, .m=mdir.m}}; + .mdir={.mid=LFSR_MID(mdir.mid.bid, 0), .m=mdir.m}}; lfsr_openedmdir_t right_neighbor = { - .mdir={.mid=mdir.mid, .rid=2, .m=mdir.m}}; + .mdir={.mid=LFSR_MID(mdir.mid.bid, 2), .m=mdir.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -3221,7 +3221,7 @@ code = ''' assert(memcmp(buffer, &alphas[2 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 3); lfsr_mdir_get(&lfs, &mdir, 1, LFSR_TAG_INLINED, @@ -3230,12 +3230,12 @@ code = ''' // assert that our neighbors were updated correctly assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(left_neighbor.mdir.mid == 0); - assert(left_neighbor.mdir.rid == 0); + assert(left_neighbor.mdir.mid.bid == 0); + assert(left_neighbor.mdir.mid.rid == 0); assert(memcmp(&left_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); - assert(right_neighbor.mdir.mid == 0); - assert(right_neighbor.mdir.rid == 2); + assert(right_neighbor.mdir.mid.bid == 0); + assert(right_neighbor.mdir.mid.rid == 2); assert(memcmp(&right_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); @@ -3279,7 +3279,7 @@ code = ''' // now force one of our siblings to split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( @@ -3297,20 +3297,20 @@ code = ''' // setup our neighbors lfsr_openedmdir_t left_neighbor; - lfsr_mtree_lookup(&lfs, 0, -1, &left_neighbor.mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &left_neighbor.mdir) => 0; assert(left_neighbor.mdir.m.rbyd.weight == 1); - left_neighbor.mdir.rid = 0; + left_neighbor.mdir.mid.rid = 0; lfsr_openedmdir_t right_neighbor; - lfsr_mtree_lookup(&lfs, 2, -1, &right_neighbor.mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(2, -1), &right_neighbor.mdir) => 0; assert(right_neighbor.mdir.m.rbyd.weight == 1); - right_neighbor.mdir.rid = 0; + right_neighbor.mdir.mid.rid = 0; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); // cause middle mdir to split - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[3 % 26], SIZE); lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( @@ -3325,14 +3325,14 @@ code = ''' // assert that our neighbors were updated correctly assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(left_neighbor.mdir.mid == 0); - assert(left_neighbor.mdir.rid == 0); - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(left_neighbor.mdir.mid.bid == 0); + assert(left_neighbor.mdir.mid.rid == 0); + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(memcmp(&left_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); - assert(right_neighbor.mdir.mid == 3); - assert(right_neighbor.mdir.rid == 0); - lfsr_mtree_lookup(&lfs, 3, -1, &mdir) => 0; + assert(right_neighbor.mdir.mid.bid == 3); + assert(right_neighbor.mdir.mid.rid == 0); + lfsr_mtree_lookup(&lfs, LFSR_MID(3, -1), &mdir) => 0; assert(memcmp(&right_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); @@ -3376,7 +3376,7 @@ code = ''' // now force one of our siblings to split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( @@ -3394,20 +3394,20 @@ code = ''' // setup our neighbors lfsr_openedmdir_t left_neighbor; - lfsr_mtree_lookup(&lfs, 0, -1, &left_neighbor.mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &left_neighbor.mdir) => 0; assert(left_neighbor.mdir.m.rbyd.weight == 1); - left_neighbor.mdir.rid = 0; + left_neighbor.mdir.mid.rid = 0; lfsr_openedmdir_t right_neighbor; - lfsr_mtree_lookup(&lfs, 2, -1, &right_neighbor.mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(2, -1), &right_neighbor.mdir) => 0; assert(right_neighbor.mdir.m.rbyd.weight == 1); - right_neighbor.mdir.rid = 0; + right_neighbor.mdir.mid.rid = 0; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); // cause middle mdir to drop - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; @@ -3417,15 +3417,15 @@ code = ''' // assert that our neighbors were updated correctly assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(left_neighbor.mdir.mid == 0); - assert(left_neighbor.mdir.rid == 0); - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(left_neighbor.mdir.mid.bid == 0); + assert(left_neighbor.mdir.mid.rid == 0); + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(memcmp(&left_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); - assert(right_neighbor.mdir.mid == 1); - assert(right_neighbor.mdir.rid == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + assert(right_neighbor.mdir.mid.bid == 1); + assert(right_neighbor.mdir.mid.rid == 0); + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(memcmp(&right_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); @@ -3473,7 +3473,7 @@ code = ''' // a bit hacky, but this catches infinite loops assert(i < 2*1); - lfs_size_t mid_; + lfsr_mid_t mid_; lfsr_tag_t tag_; lfsr_data_t data_; int err = lfsr_mtree_traversal_next(&lfs, &traversal, @@ -3485,8 +3485,9 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.buf.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_.bid, + mid_.rid, tag_, branch->block, branch->trunk); @@ -3494,8 +3495,9 @@ code = ''' seen[branch->block / 8] |= 1 << (branch->block % 8); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.buf.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_.bid, + mid_.rid, tag_, mdir->m.rbyd.block, mdir->m.redund_block); @@ -3504,8 +3506,9 @@ code = ''' seen[mdir->m.redund_block / 8] |= 1 << (mdir->m.redund_block % 8); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_.bid, + mid_.rid, tag_, lfsr_data_size(data_)); assert(false); @@ -3577,7 +3580,7 @@ code = ''' // assert that our entry is still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -3595,7 +3598,7 @@ code = ''' // a bit hacky, but this catches infinite loops assert(i < 2*2); - lfs_size_t mid_; + lfsr_mid_t mid_; lfsr_tag_t tag_; lfsr_data_t data_; int err = lfsr_mtree_traversal_next(&lfs, &traversal, @@ -3607,8 +3610,9 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.buf.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_.bid, + mid_.rid, tag_, branch->block, branch->trunk); @@ -3616,8 +3620,9 @@ code = ''' seen[branch->block / 8] |= 1 << (branch->block % 8); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.buf.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_.bid, + mid_.rid, tag_, mdir->m.rbyd.block, mdir->m.redund_block); @@ -3626,8 +3631,9 @@ code = ''' seen[mdir->m.redund_block / 8] |= 1 << (mdir->m.redund_block % 8); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_.bid, + mid_.rid, tag_, lfsr_data_size(data_)); assert(false); @@ -3658,7 +3664,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -3704,14 +3710,14 @@ code = ''' // assert that our entries are still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); lfsr_mdir_t msibling; - lfsr_mtree_lookup(&lfs, 1, -1, &msibling) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &msibling) => 0; assert(msibling.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &msibling, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -3728,7 +3734,7 @@ code = ''' // a bit hacky, but this catches infinite loops assert(i < 2*3); - lfs_size_t mid_; + lfsr_mid_t mid_; lfsr_tag_t tag_; lfsr_data_t data_; int err = lfsr_mtree_traversal_next(&lfs, &traversal, @@ -3740,8 +3746,9 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.buf.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_.bid, + mid_.rid, tag_, branch->block, branch->trunk); @@ -3749,8 +3756,9 @@ code = ''' seen[branch->block / 8] |= 1 << (branch->block % 8); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.buf.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_.bid, + mid_.rid, tag_, mdir->m.rbyd.block, mdir->m.redund_block); @@ -3759,8 +3767,9 @@ code = ''' seen[mdir->m.redund_block / 8] |= 1 << (mdir->m.redund_block % 8); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_.bid, + mid_.rid, tag_, lfsr_data_size(data_)); assert(false); @@ -3786,13 +3795,13 @@ code = ''' assert(lfs.mroot.m.rbyd.weight == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &msibling) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &msibling) => 0; assert(msibling.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &msibling, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -3853,7 +3862,7 @@ code = ''' // a bit hacky, but this catches infinite loops assert(i < 2*3); - lfs_size_t mid_; + lfsr_mid_t mid_; lfsr_tag_t tag_; lfsr_data_t data_; int err = lfsr_mtree_traversal_next(&lfs, &traversal, @@ -3865,8 +3874,9 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.buf.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_.bid, + mid_.rid, tag_, branch->block, branch->trunk); @@ -3874,8 +3884,9 @@ code = ''' seen[branch->block / 8] |= 1 << (branch->block % 8); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.buf.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_.bid, + mid_.rid, tag_, mdir->m.rbyd.block, mdir->m.redund_block); @@ -3884,8 +3895,9 @@ code = ''' seen[mdir->m.redund_block / 8] |= 1 << (mdir->m.redund_block % 8); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_.bid, + mid_.rid, tag_, lfsr_data_size(data_)); assert(false); @@ -3934,9 +3946,9 @@ code = ''' // create entries lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(lfsr_mtree_weight(&lfs)-1, -1), &mdir) => 0; - mdir.rid = 0; + mdir.mid.rid = 0; for (lfs_size_t i = 0; i < N; i++) { // force a compaction? if (FORCE_COMPACTION) { @@ -3945,14 +3957,14 @@ code = ''' } lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; + LFSR_ATTR(mdir.mid.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); - mdir.rid += 1; + mdir.mid.rid += 1; } // try looking up each entry @@ -3961,12 +3973,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -3985,7 +3997,7 @@ code = ''' // a bit hacky, but this catches infinite loops assert(i < 2*(1+N)); - lfs_size_t mid_; + lfsr_mid_t mid_; lfsr_tag_t tag_; lfsr_data_t data_; int err = lfsr_mtree_traversal_next(&lfs, &traversal, @@ -3997,8 +4009,9 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.buf.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_.bid, + mid_.rid, tag_, branch->block, branch->trunk); @@ -4006,8 +4019,9 @@ code = ''' seen[branch->block / 8] |= 1 << (branch->block % 8); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.buf.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_.bid, + mid_.rid, tag_, mdir->m.rbyd.block, mdir->m.redund_block); @@ -4016,8 +4030,9 @@ code = ''' seen[mdir->m.redund_block / 8] |= 1 << (mdir->m.redund_block % 8); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_.bid, + mid_.rid, tag_, lfsr_data_size(data_)); assert(false); @@ -4043,12 +4058,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -4087,9 +4102,9 @@ code = ''' : (lfs_ssize_t)(TEST_PRNG(&prng) % lfsr_mtree_weight(&lfs)); // fetch mdir lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // choose a pseudo-random rid - mdir.rid = TEST_PRNG(&prng) % (mdir.m.rbyd.weight+1); + mdir.mid.rid = TEST_PRNG(&prng) % (mdir.m.rbyd.weight+1); // force a compaction? if (FORCE_COMPACTION) { @@ -4099,11 +4114,11 @@ code = ''' // add to rbyd, potentially splitting the mdir lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; + LFSR_ATTR(mdir.mid.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; // make sure we can look up the new entry uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); @@ -4117,12 +4132,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -4145,7 +4160,7 @@ code = ''' // a bit hacky, but this catches infinite loops assert(i < 2*(1+N)); - lfs_size_t mid_; + lfsr_mid_t mid_; lfsr_tag_t tag_; lfsr_data_t data_; int err = lfsr_mtree_traversal_next(&lfs, &traversal, @@ -4157,8 +4172,9 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.buf.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_.bid, + mid_.rid, tag_, branch->block, branch->trunk); @@ -4166,8 +4182,9 @@ code = ''' seen[branch->block / 8] |= 1 << (branch->block % 8); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.buf.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_.bid, + mid_.rid, tag_, mdir->m.rbyd.block, mdir->m.redund_block); @@ -4176,8 +4193,9 @@ code = ''' seen[mdir->m.redund_block / 8] |= 1 << (mdir->m.redund_block % 8); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_.bid, + mid_.rid, tag_, lfsr_data_size(data_)); assert(false); @@ -4204,12 +4222,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -4249,7 +4267,7 @@ code = ''' // assert that we detect the cycle in a reasonable number of iterations assert(i < 1024); - lfs_size_t mid_; + lfsr_mid_t mid_; lfsr_tag_t tag_; lfsr_data_t data_; int err = lfsr_mtree_traversal_next(&lfs, &traversal, @@ -4261,20 +4279,23 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.buf.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_.bid, + mid_.rid, tag_, branch->block, branch->trunk); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.buf.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_.bid, + mid_.rid, tag_, mdir->m.rbyd.block, mdir->m.redund_block); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_.bid, + mid_.rid, tag_, lfsr_data_size(data_)); assert(false); diff --git a/tests/t4_alloc.toml b/tests/t4_alloc.toml index 611a9cd4..80fc7a03 100644 --- a/tests/t4_alloc.toml +++ b/tests/t4_alloc.toml @@ -108,8 +108,9 @@ code = ''' LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, -1, &mdir) => 0; - mdir.rid = 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(lfsr_mtree_weight(&lfs)-1, -1), + &mdir) => 0; + mdir.mid.rid = 0; lfs_size_t count = 0; while (true) { @@ -121,19 +122,19 @@ code = ''' // keep creating new metadata entries until we run out of space int err = lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, +1, &alphas[count % 26], 1))); + LFSR_ATTR(mdir.mid.rid, INLINED, +1, &alphas[count % 26], 1))); assert(!err || err == LFS_ERR_NOSPC); if (err == LFS_ERR_NOSPC) { break; } uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[count % 26], 1) == 0); count += 1; - mdir.rid += 1; + mdir.mid.rid += 1; } printf("alloced %d metadata entries in %d blocks\n", @@ -145,12 +146,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1;