From 18e1eb0b41572272d54e58f872edce36044b7459 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Mon, 31 Jul 2023 18:15:24 -0500 Subject: [PATCH] Moved rid into the mdir struct When updating any opened mdirs to keep things in sync, we need to know what rid the mdir is targeting in order to know which on-disk mdir it should follow in the case of splits. Making this rid an actual member of the mdir struct simplifies things. This adds some RAM cost, though the plan is to merge the mid/rid into a single integer, which requires this change and should actually save RAM in the long run. code stack before: 22342 after: 22204 (-0.6%) 2144 (+1.1%) --- lfs.c | 396 ++++++------ lfs.h | 13 +- tests/t3_mtree.toml | 1466 ++++++++++++++++++++++--------------------- tests/t4_alloc.toml | 24 +- 4 files changed, 963 insertions(+), 936 deletions(-) diff --git a/lfs.c b/lfs.c index f5acd56e..2633707f 100644 --- a/lfs.c +++ b/lfs.c @@ -5046,7 +5046,7 @@ static lfs_ssize_t lfsr_mptr_fromdisk(lfs_t *lfs, lfsr_mptr_t *mptr, // mdir things static inline lfsr_mptr_t lfsr_mdir_mptr(const lfsr_mdir_t *mdir) { - return LFSR_MPTR(mdir->rbyd.block, mdir->redund_block); + return LFSR_MPTR(mdir->m.rbyd.block, mdir->m.redund_block); } static inline int lfsr_mdir_cmp(const lfsr_mdir_t *a, const lfsr_mdir_t *b) { @@ -5056,7 +5056,7 @@ static inline int lfsr_mdir_cmp(const lfsr_mdir_t *a, const lfsr_mdir_t *b) { static inline bool lfsr_mdir_ismrootanchor(const lfsr_mdir_t *a) { // mrootanchor is always at 0x{0,1} // just check that at least one block is at 0x0 - return a->rbyd.block == 0 || a->redund_block == 0; + return a->m.rbyd.block == 0 || a->m.redund_block == 0; } static lfs_ssize_t lfsr_mdir_todisk(lfs_t *lfs, const lfsr_mdir_t *mdir, @@ -5065,7 +5065,7 @@ static lfs_ssize_t lfsr_mdir_todisk(lfs_t *lfs, const lfsr_mdir_t *mdir, } static inline lfs_size_t lfsr_mdir_weight(const lfsr_mdir_t *mdir) { - return mdir->rbyd.weight; + return mdir->m.rbyd.weight; } // track "opened" mdirs that may need to by updated @@ -5132,17 +5132,17 @@ static int lfsr_mdir_alloc(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t mid) { // setup mdir struct mdir->mid = mid; - mdir->redund_block = blocks[0]; - mdir->rbyd.weight = 0; - mdir->rbyd.block = blocks[1]; + mdir->m.redund_block = blocks[0]; + mdir->m.rbyd.weight = 0; + mdir->m.rbyd.block = blocks[1]; // mark mdir as needing compaction - mdir->rbyd.off = lfs->cfg->block_size; - mdir->rbyd.trunk = 0; + mdir->m.rbyd.off = lfs->cfg->block_size; + mdir->m.rbyd.trunk = 0; return 0; } static int lfsr_mdir_fetch(lfs_t *lfs, lfsr_mdir_t *mdir, - lfs_ssize_t mid, lfsr_mptr_t mptr) { + lfsr_mptr_t mptr, lfs_ssize_t mid, lfs_ssize_t rid) { // read both revision counts, try to figure out which block // has the most recent revision uint32_t revs[2] = {0, 0}; @@ -5164,15 +5164,16 @@ static int lfsr_mdir_fetch(lfs_t *lfs, lfsr_mdir_t *mdir, // try to fetch rbyds in the order of most recent to least recent for (int i = 0; i < 2; i++) { - int err = lfsr_rbyd_fetch(lfs, &mdir->rbyd, mptr.blocks[0], 0); + int err = lfsr_rbyd_fetch(lfs, &mdir->m.rbyd, mptr.blocks[0], 0); if (err && err != LFS_ERR_CORRUPT) { return err; } if (!err) { mdir->mid = mid; + mdir->rid = rid; // keep track of other block for compactions - mdir->redund_block = mptr.blocks[1]; + mdir->m.redund_block = mptr.blocks[1]; return 0; } @@ -5187,21 +5188,21 @@ static int lfsr_mdir_fetch(lfs_t *lfs, lfsr_mdir_t *mdir, static int lfsr_mdir_lookupnext(lfs_t *lfs, const lfsr_mdir_t *mdir, lfs_ssize_t id, lfsr_tag_t tag, lfs_ssize_t *id_, lfsr_tag_t *tag_, lfsr_data_t *data_) { - return lfsr_rbyd_lookupnext(lfs, &mdir->rbyd, id, tag, + return lfsr_rbyd_lookupnext(lfs, &mdir->m.rbyd, id, tag, id_, tag_, NULL, data_); } static int lfsr_mdir_lookup(lfs_t *lfs, const lfsr_mdir_t *mdir, lfs_ssize_t id, lfsr_tag_t tag, lfsr_tag_t *tag_, lfsr_data_t *data_) { - return lfsr_rbyd_lookup(lfs, &mdir->rbyd, id, tag, tag_, data_); + return lfsr_rbyd_lookup(lfs, &mdir->m.rbyd, id, tag, tag_, data_); } // TODO do we need this? // TODO move this into the tests? static lfs_ssize_t lfsr_mdir_get(lfs_t *lfs, const lfsr_mdir_t *mdir, lfs_ssize_t id, lfsr_tag_t tag, void *buffer, lfs_size_t size) { - return lfsr_rbyd_get(lfs, &mdir->rbyd, id, tag, buffer, size); + return lfsr_rbyd_get(lfs, &mdir->m.rbyd, id, tag, buffer, size); } @@ -5238,14 +5239,17 @@ 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, lfsr_mdir_t *mdir_) { +static int lfsr_mtree_lookup(lfs_t *lfs, lfs_ssize_t mid, lfs_ssize_t rid, + 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)); // looking up mroot? if (mid < 0) { - *mdir_ = lfs->mroot; + mdir_->mid = mid; + mdir_->rid = rid; + mdir_->m = lfs->mroot.m; return 0; // look up mdir in actual mtree @@ -5267,7 +5271,7 @@ static int lfsr_mtree_lookup(lfs_t *lfs, lfs_ssize_t mid, lfsr_mdir_t *mdir_) { } // fetch mdir - return lfsr_mdir_fetch(lfs, mdir_, mid, mptr); + return lfsr_mdir_fetch(lfs, mdir_, mptr, mid, rid); } } @@ -5283,7 +5287,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, LFSR_MID_MROOT, mptr); + int err = lfsr_mdir_fetch(lfs, &mdir, mptr, LFSR_MID_MROOT, -1); if (err) { return err; } @@ -5311,29 +5315,30 @@ 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_ssize_t *rid, - lfs_off_t off) { +static int lfsr_mtree_seek(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_off_t off) { // calculate new rid - lfs_off_t rid_ = *rid + off; + lfs_ssize_t rid_ = mdir->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_ >= mdir->rbyd.weight) { + while (rid_ >= (lfs_ssize_t)mdir->m.rbyd.weight) { lfs_ssize_t mid_ = mdir->mid + 1; // end of mtree? if (mid_ >= (lfs_ssize_t)lfsr_mtree_weight(lfs)) { - // make sure to update rid so seek always returns noent from now on - *rid = rid_; + // 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_; return LFS_ERR_NOENT; } - rid_ -= mdir->rbyd.weight; + rid_ -= mdir->m.rbyd.weight; - int err = lfsr_mtree_lookup(lfs, mid_, mdir); + int err = lfsr_mtree_lookup(lfs, mid_, rid_, mdir); if (err) { return err; } } - *rid = rid_; + mdir->rid = rid_; return 0; } @@ -5352,7 +5357,7 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir_, // first thing we need to do is read our current revision count uint32_t rev; - int err = lfsr_bd_read(lfs, mdir->rbyd.block, 0, sizeof(uint32_t), + int err = lfsr_bd_read(lfs, mdir->m.rbyd.block, 0, sizeof(uint32_t), &rev, sizeof(uint32_t)); if (err && err != LFS_ERR_CORRUPT) { return err; @@ -5376,7 +5381,7 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir_, // // we use whatever is on-disk to avoid needing to rewrite the // redund block - err = lfsr_bd_read(lfs, mdir_->rbyd.block, 0, sizeof(uint32_t), + err = lfsr_bd_read(lfs, mdir_->m.rbyd.block, 0, sizeof(uint32_t), &rev, sizeof(uint32_t)); if (err && err != LFS_ERR_CORRUPT) { return err; @@ -5399,28 +5404,29 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir_, } // swap our rbyds - lfs_swap32(&mdir_->rbyd.block, &mdir_->redund_block); + lfs_swap32(&mdir_->m.rbyd.block, &mdir_->m.redund_block); // update our revision count - mdir_->rbyd.off = 0; - mdir_->rbyd.trunk = 0; - mdir_->rbyd.weight = 0; - mdir_->rbyd.crc = 0; + mdir_->m.rbyd.off = 0; + mdir_->m.rbyd.trunk = 0; + mdir_->m.rbyd.weight = 0; + mdir_->m.rbyd.crc = 0; // erase, preparing for compact - err = lfsr_bd_erase(lfs, mdir_->rbyd.block); + err = lfsr_bd_erase(lfs, mdir_->m.rbyd.block); if (err) { return err; } // increment our revision count and write it to our rbyd // TODO rev things - err = lfsr_rbyd_appendrev(lfs, &mdir_->rbyd, rev + 1); + err = lfsr_rbyd_appendrev(lfs, &mdir_->m.rbyd, rev + 1); if (err) { return err; } // copy over attrs - err = lfsr_rbyd_compact(lfs, &mdir_->rbyd, start_id, end_id, &mdir->rbyd); + err = lfsr_rbyd_compact(lfs, &mdir_->m.rbyd, + start_id, end_id, &mdir->m.rbyd); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); return err; @@ -5430,7 +5436,7 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir_, // // upper layers should make sure this can't fail by limiting the // maximum commit size - err = lfsr_rbyd_appendall(lfs, &mdir_->rbyd, start_id, end_id, + err = lfsr_rbyd_appendall(lfs, &mdir_->m.rbyd, start_id, end_id, attr1s, attr1_count); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); @@ -5439,7 +5445,7 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir_, // note we don't filter attrs from our second pending list, this // is used for some auxiliary attrs in lfsr_mdir_commit - err = lfsr_rbyd_appendall(lfs, &mdir_->rbyd, -1, -1, + err = lfsr_rbyd_appendall(lfs, &mdir_->m.rbyd, -1, -1, attr2s, attr2_count); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); @@ -5448,7 +5454,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_->rbyd.weight == 0) { + if (mdir_->mid >= 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); @@ -5462,7 +5468,7 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir_, // helps avoid corner case issues when splitting/dropping if (mdir_->mid == LFSR_MID_MROOT || lfsr_mdir_cmp(mdir_, mdir) == 0) { - err = lfsr_rbyd_appendgdelta(lfs, &mdir_->rbyd); + err = lfsr_rbyd_appendgdelta(lfs, &mdir_->m.rbyd); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); return err; @@ -5475,7 +5481,7 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir_, } } - err = lfsr_rbyd_commit(lfs, &mdir_->rbyd, NULL, 0); + err = lfsr_rbyd_commit(lfs, &mdir_->m.rbyd, NULL, 0); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); return err; @@ -5502,8 +5508,8 @@ static int lfsr_mdir_commit_(lfs_t *lfs, lfsr_mdir_t *mdir, // TODO handle this differently? // TODO let the lower rbyd layer handle this somehow? // mark mdir as unerased in case we fail - mdir->rbyd.off = lfs->cfg->block_size; - int err = lfsr_rbyd_appendall(lfs, &mdir_.rbyd, start_id, end_id, + mdir->m.rbyd.off = lfs->cfg->block_size; + int err = lfsr_rbyd_appendall(lfs, &mdir_.m.rbyd, start_id, end_id, attrs, attr_count); if (err && err != LFS_ERR_RANGE) { return err; @@ -5513,7 +5519,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_.rbyd.weight == 0) { + if (mdir_.mid >= 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); @@ -5527,7 +5533,7 @@ static int lfsr_mdir_commit_(lfs_t *lfs, lfsr_mdir_t *mdir, } else { // only append gstate if we are not dropping - err = lfsr_rbyd_appendgdelta(lfs, &mdir_.rbyd); + err = lfsr_rbyd_appendgdelta(lfs, &mdir_.m.rbyd); if (err && err != LFS_ERR_RANGE) { return err; } @@ -5536,7 +5542,7 @@ static int lfsr_mdir_commit_(lfs_t *lfs, lfsr_mdir_t *mdir, } // finalize commit - err = lfsr_rbyd_commit(lfs, &mdir_.rbyd, NULL, 0); + err = lfsr_rbyd_commit(lfs, &mdir_.m.rbyd, NULL, 0); if (err && err != LFS_ERR_RANGE) { return err; } @@ -5556,7 +5562,7 @@ compact:; // can't commit, try to compact // check if we're within our compaction threshold - lfs_ssize_t estimate = lfsr_rbyd_estimateall(lfs, &mdir->rbyd, + lfs_ssize_t estimate = lfsr_rbyd_estimateall(lfs, &mdir->m.rbyd, start_id, end_id, split_id_); if (estimate < 0) { @@ -5585,10 +5591,10 @@ compact:; // // this is also responsible for updating any opened mdirs, lfs_t, gstate, etc // -static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t *rid, +static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, const lfsr_attr_t *attrs, lfs_size_t attr_count) { LFS_ASSERT(mdir->mid != LFSR_MID_RM); - LFS_ASSERT(mdir->mid == LFSR_MID_MROOT || mdir->rbyd.weight > 0); + LFS_ASSERT(mdir->mid == LFSR_MID_MROOT || mdir->m.rbyd.weight > 0); // parse out any pending gstate, these will get automatically xored // with on-disk gdeltas in lower-level functions @@ -5627,7 +5633,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t *rid, // TODO wait, do we need to update lfs->mroot and mdir eagerly // for the same reason? lfsr_mdir_t mroot_ = (mdir->mid == LFSR_MID_MROOT ? mdir_ : lfs->mroot); - lfsr_mdir_t msibling_ = {.mid=LFSR_MID_RM, .rbyd.weight = 0}; + lfsr_mdir_t msibling_ = {.mid=LFSR_MID_RM, .m.rbyd.weight = 0}; lfsr_btree_t mtree_ = lfs->mtree; bool dirtymroot = false; bool dirtymtree = false; @@ -5688,23 +5694,23 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t *rid, "-> 0x{%"PRIx32",%"PRIx32"}" ", 0x{%"PRIx32",%"PRIx32"}", mdir->mid, - mdir->rbyd.block, mdir->redund_block, - mdir_.rbyd.block, mdir_.redund_block, - msibling_.rbyd.block, msibling_.redund_block); + mdir->m.rbyd.block, mdir->m.redund_block, + mdir_.m.rbyd.block, mdir_.m.redund_block, + msibling_.m.rbyd.block, msibling_.m.redund_block); // because of defered commits, both children can still be reduced // to zero, need to catch this here // both siblings reduced to zero - if (mdir_.rbyd.weight == 0 && msibling_.rbyd.weight == 0) { + if (mdir_.m.rbyd.weight == 0 && msibling_.m.rbyd.weight == 0) { LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", mdir_.mid, - mdir_.rbyd.block, mdir_.redund_block); + mdir_.m.rbyd.block, mdir_.m.redund_block); LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", msibling_.mid, - msibling_.rbyd.block, msibling_.redund_block); - mdir_.rbyd.trunk = 0; - msibling_.rbyd.trunk = 0; + msibling_.m.rbyd.block, msibling_.m.redund_block); + mdir_.m.rbyd.trunk = 0; + msibling_.m.rbyd.trunk = 0; // update our mtree int err = lfsr_btree_pop(lfs, &mtree_, mid); @@ -5713,11 +5719,11 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t *rid, } // one sibling reduced to zero - } else if (mdir_.rbyd.weight == 0) { + } else if (mdir_.m.rbyd.weight == 0) { LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", mdir_.mid, - mdir_.rbyd.block, mdir_.redund_block); - mdir_.rbyd.trunk = 0; + mdir_.m.rbyd.block, mdir_.m.redund_block); + mdir_.m.rbyd.trunk = 0; // update our mtree uint8_t buf[LFSR_MPTR_DSIZE]; @@ -5733,11 +5739,11 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t *rid, } // other sibling reduced to zero - } else if (msibling_.rbyd.weight == 0) { + } else if (msibling_.m.rbyd.weight == 0) { LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", msibling_.mid, - msibling_.rbyd.block, msibling_.redund_block); - msibling_.rbyd.trunk = 0; + msibling_.m.rbyd.block, msibling_.m.redund_block); + msibling_.m.rbyd.trunk = 0; // update our mtree uint8_t buf[LFSR_MPTR_DSIZE]; @@ -5798,11 +5804,11 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t *rid, dirtymtree = true; // mdir reduced to zero? need to drop? - } else if (mdir->mid != LFSR_MID_MROOT && mdir_.rbyd.weight == 0) { + } else if (mdir->mid != LFSR_MID_MROOT && mdir_.m.rbyd.weight == 0) { LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", mdir->mid, - mdir->rbyd.block, mdir->redund_block); - mdir_.rbyd.trunk = 0; + mdir->m.rbyd.block, mdir->m.redund_block); + mdir_.m.rbyd.trunk = 0; // update our mtree int err = lfsr_btree_pop(lfs, &mtree_, mdir->mid); @@ -5825,8 +5831,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t *rid, LFS_DEBUG("Relocating mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"} " "-> 0x{%"PRIx32",%"PRIx32"}", mdir->mid, - mdir->rbyd.block, mdir->redund_block, - mdir_.rbyd.block, mdir_.redund_block); + mdir->m.rbyd.block, mdir->m.redund_block, + mdir_.m.rbyd.block, mdir_.m.redund_block); // update our mtree uint8_t buf[LFSR_MPTR_DSIZE]; @@ -5874,15 +5880,16 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t *rid, // fix our grm for (uint8_t j = 0; j < 2; j++) { if (grm->rms[j].mid == mdir->mid) { - LFS_ASSERT(grm->rms[j].rid <= mdir->rbyd.weight); + LFS_ASSERT(grm->rms[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); - if (grm->rms[j].rid >= mdir_.rbyd.weight) { + if (grm->rms[j].rid >= (lfs_ssize_t)mdir_.m.rbyd.weight) { grm->rms[j].mid += 1; - grm->rms[j].rid -= mdir_.rbyd.weight; + grm->rms[j].rid -= mdir_.m.rbyd.weight; } // update mid if we had a split or drop } else if (grm->rms[j].mid > mdir->mid @@ -5955,8 +5962,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t *rid, LFS_DEBUG("Relocating mroot 0x{%"PRIx32",%"PRIx32"} " "-> 0x{%"PRIx32",%"PRIx32"}", - mchildroot.rbyd.block, mchildroot.redund_block, - mchildroot_.rbyd.block, mchildroot_.redund_block); + mchildroot.m.rbyd.block, mchildroot.m.redund_block, + mchildroot_.m.rbyd.block, mchildroot_.m.redund_block); // commit mrootchild uint8_t buf[LFSR_MPTR_DSIZE]; @@ -5986,9 +5993,9 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t *rid, LFS_DEBUG("Extending mroot 0x{%"PRIx32",%"PRIx32"}" " -> 0x{%"PRIx32",%"PRIx32"}" ", 0x{%"PRIx32",%"PRIx32"}", - mchildroot.rbyd.block, mchildroot.redund_block, - mchildroot.redund_block, mchildroot.rbyd.block, - mchildroot_.rbyd.block, mchildroot_.redund_block); + mchildroot.m.rbyd.block, mchildroot.m.redund_block, + mchildroot.m.redund_block, mchildroot.m.rbyd.block, + mchildroot_.m.rbyd.block, mchildroot_.m.redund_block); // copy magic/config from current mroot lfsr_data_t magic; @@ -6058,20 +6065,20 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t *rid, // TODO clean this up a bit // adjust opened mdirs? if (opened->mdir.mid == mdir->mid - && opened->rid >= attrs[i].id) { + && opened->mdir.rid >= attrs[i].id) { // removed? - if (opened->rid + attrs[i].delta < attrs[i].id) { + if (opened->mdir.rid + attrs[i].delta < attrs[i].id) { // note we have different behavior for files and dirs // here: // - files => mark entry as removed // - dirs => adjust rid/mid to point to next entry if (type == LFS_TYPE_DIR) { - opened->rid = attrs[i].id; + opened->mdir.rid = attrs[i].id; } else { opened->mdir.mid = LFSR_MID_RM; } } else { - opened->rid += attrs[i].delta; + opened->mdir.rid += attrs[i].delta; // adjust dir position? if (type == LFS_TYPE_DIR && ((((lfsr_dir_t*)opened)->dstart_mid @@ -6112,15 +6119,19 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t *rid, } // update mid if we had a split or drop - if (opened->mdir.mid == mdir->mid && opened->mdir.rbyd.weight > 0) { - if (msibling_.rbyd.weight > 0 - && opened->rid >= (lfs_ssize_t)mdir_.rbyd.weight) { + if (opened->mdir.mid == mdir->mid + && opened->mdir.m.rbyd.weight > 0) { + if (msibling_.m.rbyd.weight > 0 + && opened->mdir.rid + >= (lfs_ssize_t)mdir_.m.rbyd.weight) { LFS_ASSERT(lfsr_btree_weight(&mtree_) != lfsr_mtree_weight(lfs)); - opened->rid -= mdir_.rbyd.weight; - opened->mdir = msibling_; + opened->mdir.mid = msibling_.mid; + opened->mdir.rid -= mdir_.m.rbyd.weight; + opened->mdir.m = msibling_.m; } else { - opened->mdir = mdir_; + opened->mdir.mid = mdir_.mid; + opened->mdir.m = mdir_.m; } } else if (opened->mdir.mid > mdir->mid) { opened->mdir.mid += lfsr_btree_weight(&mtree_) @@ -6130,12 +6141,13 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t *rid, // update dstarts if we had a split or drop if (type == LFS_TYPE_DIR) { if (((lfsr_dir_t*)opened)->dstart_mid == mdir->mid) { - if (msibling_.rbyd.weight > 0 + if (msibling_.m.rbyd.weight > 0 && ((lfsr_dir_t*)opened)->dstart_rid - >= (lfs_ssize_t)mdir_.rbyd.weight) { + >= (lfs_ssize_t)mdir_.m.rbyd.weight) { LFS_ASSERT(lfsr_btree_weight(&mtree_) != lfsr_mtree_weight(lfs)); - ((lfsr_dir_t*)opened)->dstart_rid -= mdir_.rbyd.weight; + ((lfsr_dir_t*)opened)->dstart_rid + -= mdir_.m.rbyd.weight; ((lfsr_dir_t*)opened)->dstart_mid = msibling_.mid; } else { ((lfsr_dir_t*)opened)->dstart_mid = mdir_.mid; @@ -6150,21 +6162,21 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t *rid, } // update mdir to follow requested rid - lfs_ssize_t rid_ = *rid; - LFS_ASSERT(rid_ <= (lfs_ssize_t)mdir->rbyd.weight); - if (rid_ == -1) { - *mdir = mroot_; - } else if ((lfs_size_t)rid_ >= mdir_.rbyd.weight) { + LFS_ASSERT(mdir->rid <= (lfs_ssize_t)mdir->m.rbyd.weight); + if (mdir->mid < 0 && mdir->rid < 0) { + mdir->m = mroot_.m; + } else if (mdir->rid >= (lfs_ssize_t)mdir_.m.rbyd.weight) { // note removes can trigger this incorrectly, but we don't really // care, the rid was removed after all - *rid = rid_ - mdir_.rbyd.weight; - *mdir = msibling_; + mdir->mid = msibling_.mid; + mdir->rid -= mdir_.m.rbyd.weight; + mdir->m = msibling_.m; } else { - *mdir = mdir_; + mdir->m = mdir_.m; } // update our mroot and mtree - lfs->mroot = mroot_; + lfs->mroot.m = mroot_.m; lfs->mtree = mtree_; return 0; @@ -6175,7 +6187,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t *rid, static int lfsr_mdir_dnamelookup(lfs_t *lfs, const lfsr_mdir_t *mdir, lfs_size_t did, const char *name, lfs_size_t name_size, lfs_ssize_t *id_, lfsr_tag_t *tag_, lfsr_data_t *data_) { - int err = lfsr_rbyd_dnamelookup(lfs, &mdir->rbyd, + int err = lfsr_rbyd_dnamelookup(lfs, &mdir->m.rbyd, did, name, name_size, id_, tag_, NULL, data_); @@ -6193,8 +6205,7 @@ static int lfsr_mdir_dnamelookup(lfs_t *lfs, const lfsr_mdir_t *mdir, // note if we fail, we at least leave mdir_/rid_ with the best place to insert static int lfsr_mtree_dnamelookup(lfs_t *lfs, lfs_size_t did, const char *name, lfs_size_t name_size, - lfsr_mdir_t *mdir_, lfs_ssize_t *rid_, lfsr_tag_t *tag_, - lfsr_data_t *data_) { + lfsr_mdir_t *mdir_, lfsr_tag_t *tag_, lfsr_data_t *data_) { // do we only have mroot? lfsr_mdir_t mdir; if (lfsr_mtree_isinlined(lfs)) { @@ -6221,7 +6232,7 @@ static int lfsr_mtree_dnamelookup(lfs_t *lfs, } // fetch mdir - err = lfsr_mdir_fetch(lfs, &mdir, mid, mptr); + err = lfsr_mdir_fetch(lfs, &mdir, mptr, mid, -1); if (err) { return err; } @@ -6234,7 +6245,7 @@ static int lfsr_mtree_dnamelookup(lfs_t *lfs, // and finally lookup dname in our mdir return lfsr_mdir_dnamelookup(lfs, &mdir, did, name, name_size, - rid_, tag_, data_); + (mdir_ ? &mdir_->rid : NULL), tag_, data_); } @@ -6245,25 +6256,21 @@ enum { // lookup full paths in our mtree // -// if not found, mdir_/rid_/did_/name_ will at least be set up +// if not found, mdir_/did_/name_ will at least be set up // with what should be the parent static int lfsr_mtree_pathlookup(lfs_t *lfs, const char *path, // TODO originally path itself was a double pointer, is that a // better design? - lfsr_mdir_t *mdir_, lfs_ssize_t *rid_, lfsr_tag_t *tag_, + 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 = {.mid = LFSR_MID_RM}; - lfs_ssize_t rid = -1; + lfsr_mdir_t mdir = {.mid = LFSR_MID_RM, .rid = -1}; lfsr_tag_t tag = LFSR_TAG_DIR; lfs_size_t did = LFSR_DID_ROOT; if (mdir_) { *mdir_ = mdir; } - if (rid_) { - *rid_ = rid; - } if (tag_) { *tag_ = tag; } @@ -6311,7 +6318,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 (rid == -1) { + if (mdir.rid == -1) { return LFS_ERR_INVAL; } return 0; @@ -6323,9 +6330,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 (rid != -1) { + if (mdir.rid != -1) { lfsr_data_t data; - int err = lfsr_mdir_lookup(lfs, &mdir, rid, LFSR_TAG_DID, + int err = lfsr_mdir_lookup(lfs, &mdir, mdir.rid, LFSR_TAG_DID, NULL, &data); if (err) { return err; @@ -6339,7 +6346,7 @@ static int lfsr_mtree_pathlookup(lfs_t *lfs, const char *path, // lookup up this dname in the mtree int err = lfsr_mtree_dnamelookup(lfs, did, name, name_size, - &mdir, &rid, &tag, NULL); + &mdir, &tag, NULL); if (err && err != LFS_ERR_NOENT) { return err; } @@ -6350,9 +6357,6 @@ static int lfsr_mtree_pathlookup(lfs_t *lfs, const char *path, if (mdir_) { *mdir_ = mdir; } - if (rid_) { - *rid_ = rid; - } if (tag_) { *tag_ = tag; } @@ -6367,8 +6371,8 @@ static int lfsr_mtree_pathlookup(lfs_t *lfs, const char *path, } } - // error if not found, note we update things first so mdir/rid - // get updated with where to insert correctly + // error if not found, note we update things first so mdir + // gets updated with where to insert correctly if (err == LFS_ERR_NOENT) { return LFS_ERR_NOENT; } @@ -6399,7 +6403,7 @@ enum { #define LFSR_MTREE_TRAVERSAL_INIT(_flags) ((lfsr_mtree_traversal_t){ \ .flags = _flags, \ - .mdir.rbyd.trunk = 0, \ + .mdir.m.rbyd.trunk = 0, \ .mtraversal = LFSR_BTREE_TRAVERSAL_INIT, \ .tortoise_power = 0, \ .tortoise_step = 0, \ @@ -6412,10 +6416,10 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs, // // note we make sure to include fake mroots! // - if (traversal->mdir.rbyd.trunk == 0) { + if (traversal->mdir.m.rbyd.trunk == 0) { // fetch the first mroot 0x{0,1} int err = lfsr_mdir_fetch(lfs, &traversal->mdir, - LFSR_MID_MROOT, LFSR_MPTR_MROOTANCHOR); + LFSR_MPTR_MROOTANCHOR, LFSR_MID_MROOT, -1); if (err) { return err; } @@ -6452,7 +6456,7 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs, } int err = lfsr_mdir_fetch(lfs, &traversal->mdir, - LFSR_MID_MROOT, mptr); + mptr, LFSR_MID_MROOT, -1); if (err) { return err; } @@ -6570,7 +6574,7 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs, return d; } - int err = lfsr_mdir_fetch(lfs, &traversal->mdir, mid, mptr); + int err = lfsr_mdir_fetch(lfs, &traversal->mdir, mptr, mid, -1); if (err) { return err; } @@ -6603,7 +6607,7 @@ cycle_detect:; traversal->tortoise_mptr) == 0) { LFS_ERROR("Cycle detected during mtree traversal " "(0x{%"PRIx32",%"PRIx32"})", - traversal->mdir.rbyd.block, traversal->mdir.redund_block); + traversal->mdir.m.rbyd.block, traversal->mdir.m.redund_block); return LFS_ERR_CORRUPT; } if (traversal->tortoise_step @@ -7204,8 +7208,8 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) { // mark any blocks we see at in-use, including any btree/mdir blocks if (tag == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data.buf.buffer; - lfs_alloc_setinuse(lfs, mdir->rbyd.block); - lfs_alloc_setinuse(lfs, mdir->redund_block); + lfs_alloc_setinuse(lfs, mdir->m.rbyd.block); + lfs_alloc_setinuse(lfs, mdir->m.redund_block); } else if (tag == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t*)data.buf.buffer; @@ -7231,9 +7235,9 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) { const char *name; lfs_size_t name_size; err = lfsr_mtree_pathlookup(lfs, path, - &parent.mdir, &parent.rid, NULL, + &parent.mdir, NULL, &parent_did, &name, &name_size); - if (err && (err != LFS_ERR_NOENT || parent.rid == -1)) { + if (err && (err != LFS_ERR_NOENT || parent.mdir.rid == -1)) { return err; } @@ -7282,10 +7286,9 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) { // Check if we have a collision. If we do, search for the next // available did lfsr_mdir_t mdir; - lfs_ssize_t rid; while (true) { int err = lfsr_mtree_dnamelookup(lfs, did, NULL, 0, - &mdir, &rid, NULL, NULL); + &mdir, NULL, NULL); if (err && err != LFS_ERR_NOENT) { return err; } @@ -7303,7 +7306,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.rid -= 1; + parent.mdir.rid -= 1; lfsr_mdir_addopened(lfs, LFS_TYPE_REG, &parent); // Conveniently, we just found where our dstart should go. The dstart @@ -7312,23 +7315,24 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) { // We include a GRM here so the dstart is automatically removed if we // lose power before writing the entry in our parent // - err = lfsr_mdir_commit(lfs, &mdir, &rid, LFSR_ATTRS( - LFSR_ATTR_DNAME(rid, DSTART, +1, did, NULL, 0), + 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=rid}, + {.mid=mdir.mid, .rid=mdir.rid}, {.mid=LFSR_MID_RM}}})))); if (err) { goto failed_with_parent; } lfsr_mdir_removeopened(lfs, LFS_TYPE_REG, &parent); - parent.rid += 1; + parent.mdir.rid += 1; // commit our new directory into our parent, zeroing out our grm // in the process - err = lfsr_mdir_commit(lfs, &parent.mdir, &parent.rid, LFSR_ATTRS( - LFSR_ATTR_DNAME(parent.rid, DIR, +1, parent_did, name, name_size), - LFSR_ATTR_LEB128(parent.rid, DID, 0, did), + err = lfsr_mdir_commit(lfs, &parent.mdir, LFSR_ATTRS( + LFSR_ATTR_DNAME(parent.mdir.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=LFSR_MID_RM}, {.mid=LFSR_MID_RM}}})))); @@ -7352,10 +7356,9 @@ int lfsr_remove(lfs_t *lfs, const char *path) { // lookup our entry lfsr_mdir_t mdir; - lfs_ssize_t rid; lfsr_tag_t tag; err = lfsr_mtree_pathlookup(lfs, path, - &mdir, &rid, &tag, + &mdir, &tag, NULL, NULL, NULL); if (err) { return err; @@ -7367,7 +7370,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, rid, LFSR_TAG_DID, + int err = lfsr_mdir_lookup(lfs, &mdir, mdir.rid, LFSR_TAG_DID, NULL, &data); if (err) { return err; @@ -7381,26 +7384,25 @@ int lfsr_remove(lfs_t *lfs, const char *path) { // then lookup the dstart entry lfsr_mdir_t mdir_; - lfs_ssize_t rid_; err = lfsr_mtree_dnamelookup(lfs, did, NULL, 0, - &mdir_, &rid_, NULL, NULL); + &mdir_, NULL, NULL); if (err) { LFS_ASSERT(err != LFS_ERR_NOENT); return err; } // create a grm to remove the dstart entry - lfsr_grm_pushrm(&grm, mdir_.mid, rid_); + lfsr_grm_pushrm(&grm, mdir_.mid, mdir_.rid); // check that the directory is empty - err = lfsr_mtree_seek(lfs, &mdir_, &rid_, 1); + err = lfsr_mtree_seek(lfs, &mdir_, 1); if (err && err != LFS_ERR_NOENT) { return err; } if (err != LFS_ERR_NOENT) { lfsr_tag_t tag_; - err = lfsr_mdir_lookup(lfs, &mdir_, rid_, LFSR_TAG_WIDENAME, + err = lfsr_mdir_lookup(lfs, &mdir_, mdir_.rid, LFSR_TAG_WIDENAME, &tag_, NULL); if (err) { return err; @@ -7412,15 +7414,14 @@ 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 - && (lfs_ssize_t)grm.rms[0].rid > rid) { + if (grm.rms[0].mid == mdir.mid && grm.rms[0].rid > mdir.rid) { grm.rms[0].rid -= 1; } } // remove the metadata entry - err = lfsr_mdir_commit(lfs, &mdir, &rid, LFSR_ATTRS( - LFSR_ATTR(rid, UNR, -1, NULL, 0), + err = lfsr_mdir_commit(lfs, &mdir, LFSR_ATTRS( + LFSR_ATTR(mdir.rid, UNR, -1, NULL, 0), LFSR_ATTR_GRM(-1, GRM, 0, &grm))); if (err) { return err; @@ -7440,10 +7441,9 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { // lookup old entry lfsr_mdir_t old_mdir; - lfs_ssize_t old_rid; lfsr_tag_t old_tag; err = lfsr_mtree_pathlookup(lfs, old_path, - &old_mdir, &old_rid, &old_tag, + &old_mdir, &old_tag, NULL, NULL, NULL); if (err) { return err; @@ -7451,19 +7451,18 @@ 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_rid); + lfsr_grm_pushrm(&grm, old_mdir.mid, old_mdir.rid); // lookup new entry lfsr_mdir_t new_mdir; - lfs_ssize_t new_rid; lfsr_tag_t new_tag; lfs_size_t new_did; const char *new_name; lfs_size_t new_name_size; err = lfsr_mtree_pathlookup(lfs, new_path, - &new_mdir, &new_rid, &new_tag, + &new_mdir, &new_tag, &new_did, &new_name, &new_name_size); - if (err && (err != LFS_ERR_NOENT || new_rid == -1)) { + if (err && (err != LFS_ERR_NOENT || new_mdir.rid == -1)) { return err; } bool exists = (err != LFS_ERR_NOENT); @@ -7476,8 +7475,7 @@ 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 - && (lfs_ssize_t)grm.rms[0].rid >= new_rid) { + if (grm.rms[0].mid == new_mdir.mid && grm.rms[0].rid >= new_mdir.rid) { grm.rms[0].rid += 1; } @@ -7489,7 +7487,7 @@ 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_rid == new_rid) { + if (old_mdir.mid == new_mdir.mid && old_mdir.rid == new_mdir.rid) { return 0; } @@ -7499,7 +7497,8 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { // TODO deduplicate the isempty check with lfsr_remove? // first lets figure out the did lfsr_data_t data; - int err = lfsr_mdir_lookup(lfs, &new_mdir, new_rid, LFSR_TAG_DID, + int err = lfsr_mdir_lookup(lfs, &new_mdir, + new_mdir.rid, LFSR_TAG_DID, NULL, &data); if (err) { return err; @@ -7513,26 +7512,26 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { // then lookup the dstart entry lfsr_mdir_t mdir_; - lfs_ssize_t rid_; err = lfsr_mtree_dnamelookup(lfs, did, NULL, 0, - &mdir_, &rid_, NULL, NULL); + &mdir_, NULL, NULL); if (err) { LFS_ASSERT(err != LFS_ERR_NOENT); return err; } // create a grm to remove the dstart entry - lfsr_grm_pushrm(&grm, mdir_.mid, rid_); + lfsr_grm_pushrm(&grm, mdir_.mid, mdir_.rid); // check that the directory is empty - err = lfsr_mtree_seek(lfs, &mdir_, &rid_, 1); + err = lfsr_mtree_seek(lfs, &mdir_, 1); if (err && err != LFS_ERR_NOENT) { return err; } if (err != LFS_ERR_NOENT) { lfsr_tag_t tag_; - err = lfsr_mdir_lookup(lfs, &mdir_, rid_, LFSR_TAG_WIDENAME, + err = lfsr_mdir_lookup(lfs, &mdir_, + mdir_.rid, LFSR_TAG_WIDENAME, &tag_, NULL); if (err) { return err; @@ -7547,13 +7546,14 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { // rename our entry, copying all tags associated with the old rid to the // new rid, while also marking the old rid for removal - err = lfsr_mdir_commit(lfs, &new_mdir, &new_rid, LFSR_ATTRS( + err = lfsr_mdir_commit(lfs, &new_mdir, LFSR_ATTRS( (exists - ? LFSR_ATTR(new_rid, UNR, -1, NULL, 0) + ? LFSR_ATTR(new_mdir.rid, UNR, -1, NULL, 0) : LFSR_ATTR_NOOP), - LFSR_ATTR_DNAME_(new_rid, old_tag, +1, + LFSR_ATTR_DNAME_(new_mdir.rid, old_tag, +1, new_did, new_name, new_name_size), - LFSR_ATTR_MOVE(new_rid, MOVE, 0, &old_mdir.rbyd, old_rid), + LFSR_ATTR_MOVE(new_mdir.rid, MOVE, 0, + &old_mdir.m.rbyd, old_mdir.rid), LFSR_ATTR_GRM(-1, GRM, 0, &grm))); // we need to clean up any pending grms, fortunately we can leave @@ -7566,12 +7566,11 @@ int lfsr_stat(lfs_t *lfs, const char *path, struct lfs_info *info) { // lookup our entry lfsr_mdir_t mdir; - lfs_ssize_t rid; lfsr_tag_t tag; const char *name; lfs_size_t name_size; int err = lfsr_mtree_pathlookup(lfs, path, - &mdir, &rid, &tag, + &mdir, &tag, NULL, &name, &name_size); if (err && err != LFS_ERR_INVAL) { return err; @@ -7599,10 +7598,9 @@ int lfsr_stat(lfs_t *lfs, const char *path, struct lfs_info *info) { int lfsr_dir_open(lfs_t *lfs, lfsr_dir_t *dir, const char *path) { // lookup our directory lfsr_mdir_t mdir; - lfs_ssize_t rid; lfsr_tag_t tag; int err = lfsr_mtree_pathlookup(lfs, path, - &mdir, &rid, &tag, + &mdir, &tag, NULL, NULL, NULL); if (err && err != LFS_ERR_INVAL) { return err; @@ -7618,7 +7616,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, rid, LFSR_TAG_DID, + int err = lfsr_mdir_lookup(lfs, &mdir, mdir.rid, LFSR_TAG_DID, NULL, &data); if (err) { return err; @@ -7635,32 +7633,32 @@ int lfsr_dir_open(lfs_t *lfs, lfsr_dir_t *dir, const char *path) { // lookup our dstart in the mtree err = lfsr_mtree_dnamelookup(lfs, dir->did, NULL, 0, - &dir->mdir.mdir, &dir->mdir.rid, NULL, NULL); + &dir->m.mdir, NULL, NULL); if (err) { LFS_ASSERT(err != LFS_ERR_NOENT); return err; } // keep track of the mid/rid of our dstart - dir->dstart_mid = dir->mdir.mdir.mid; - dir->dstart_rid = dir->mdir.rid; + dir->dstart_mid = dir->m.mdir.mid; + dir->dstart_rid = dir->m.mdir.rid; // eagerly look up the next entry // // this makes handling of corner cases with mixed removes/dir reads easier - err = lfsr_mtree_seek(lfs, &dir->mdir.mdir, &dir->mdir.rid, 1); + err = lfsr_mtree_seek(lfs, &dir->m.mdir, 1); if (err && err != LFS_ERR_NOENT) { return err; } // add to tracked mdirs - lfsr_mdir_addopened(lfs, LFS_TYPE_DIR, &dir->mdir); + lfsr_mdir_addopened(lfs, LFS_TYPE_DIR, &dir->m); return 0; } int lfsr_dir_close(lfs_t *lfs, lfsr_dir_t *dir) { // remove from tracked mdirs - lfsr_mdir_removeopened(lfs, LFS_TYPE_DIR, &dir->mdir); + lfsr_mdir_removeopened(lfs, LFS_TYPE_DIR, &dir->m); return 0; } @@ -7681,7 +7679,7 @@ int lfsr_dir_read(lfs_t *lfs, lfsr_dir_t *dir, struct lfs_info *info) { } // seek in case our mdir was dropped - int err = lfsr_mtree_seek(lfs, &dir->mdir.mdir, &dir->mdir.rid, 0); + int err = lfsr_mtree_seek(lfs, &dir->m.mdir, 0); if (err) { return err; } @@ -7689,8 +7687,8 @@ int lfsr_dir_read(lfs_t *lfs, lfsr_dir_t *dir, struct lfs_info *info) { // lookup our name tag lfsr_tag_t tag; lfsr_data_t data; - err = lfsr_mdir_lookup(lfs, &dir->mdir.mdir, - dir->mdir.rid, LFSR_TAG_WIDENAME, + err = lfsr_mdir_lookup(lfs, &dir->m.mdir, + dir->m.mdir.rid, LFSR_TAG_WIDENAME, &tag, &data); if (err) { return err; @@ -7722,7 +7720,7 @@ int lfsr_dir_read(lfs_t *lfs, lfsr_dir_t *dir, struct lfs_info *info) { // TODO get size once we actually have regular files // eagerly look up the next entry - err = lfsr_mtree_seek(lfs, &dir->mdir.mdir, &dir->mdir.rid, 1); + err = lfsr_mtree_seek(lfs, &dir->m.mdir, 1); if (err && err != LFS_ERR_NOENT) { return err; } @@ -7743,7 +7741,7 @@ int lfsr_dir_seek(lfs_t *lfs, lfsr_dir_t *dir, lfs_off_t off) { // // note the -2 to adjust for dot entries if (off > 2) { - err = lfsr_mtree_seek(lfs, &dir->mdir.mdir, &dir->mdir.rid, off - 2); + err = lfsr_mtree_seek(lfs, &dir->m.mdir, off - 2); if (err && err != LFS_ERR_NOENT) { return err; } @@ -7768,17 +7766,17 @@ int lfsr_dir_rewind(lfs_t *lfs, lfsr_dir_t *dir) { dir->pos = 0; // lookup our dstart in the mtree again - int err = lfsr_mtree_lookup(lfs, dir->dstart_mid, &dir->mdir.mdir); + int err = lfsr_mtree_lookup(lfs, dir->dstart_mid, dir->dstart_rid, + &dir->m.mdir); if (err) { LFS_ASSERT(err != LFS_ERR_NOENT); return err; } - dir->mdir.rid = dir->dstart_rid; // eagerly look up the next entry // // this makes handling of corner cases with mixed removes/dir reads easier - err = lfsr_mtree_seek(lfs, &dir->mdir.mdir, &dir->mdir.rid, 1); + err = lfsr_mtree_seek(lfs, &dir->m.mdir, 1); if (err && err != LFS_ERR_NOENT) { return err; } @@ -7794,7 +7792,9 @@ static int lfsr_fs_fixgrm(lfs_t *lfs) { // 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, &mdir); + int err = lfsr_mtree_lookup(lfs, + lfs->grm.rms[0].mid, lfs->grm.rms[0].rid, + &mdir); if (err) { return err; } @@ -7804,17 +7804,15 @@ static int lfsr_fs_fixgrm(lfs_t *lfs) { lfsr_grm_poprm(&grm); // make sure to adjust any remaining grms - if (grm.rms[0].mid == lfs->grm.rms[0].mid - && grm.rms[0].rid >= lfs->grm.rms[0].rid) { - LFS_ASSERT(grm.rms[0].rid != lfs->grm.rms[0].rid); + 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; } // remove the rid while also updating our grm - LFS_ASSERT(lfs->grm.rms[0].rid < mdir.rbyd.weight); - err = lfsr_mdir_commit(lfs, &mdir, - &(lfs_ssize_t){lfs->grm.rms[0].rid}, LFSR_ATTRS( - LFSR_ATTR(lfs->grm.rms[0].rid, UNR, -1, NULL, 0), + LFS_ASSERT(lfs->grm.rms[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_GRM(-1, GRM, 0, &grm))); } diff --git a/lfs.h b/lfs.h index 7c60a8dd..1ddc32d9 100644 --- a/lfs.h +++ b/lfs.h @@ -373,14 +373,15 @@ typedef struct lfsr_mdir { // -1 => mroot // >=0 => bid in the mtree lfs_ssize_t mid; - lfsr_rbyd_t rbyd; - lfs_block_t redund_block; + lfs_ssize_t rid; + struct { + lfsr_rbyd_t rbyd; + lfs_block_t redund_block; + } m; } lfsr_mdir_t; typedef struct lfsr_openedmdir { struct lfsr_openedmdir *next; - // this rid is followed during splits - lfs_ssize_t rid; lfsr_mdir_t mdir; } lfsr_openedmdir_t; @@ -395,7 +396,7 @@ typedef struct lfsr_openedmdir { typedef struct lfsr_grm { struct { lfs_ssize_t mid; - lfs_size_t rid; + lfs_ssize_t rid; } rms[2]; } lfsr_grm_t; @@ -423,7 +424,7 @@ typedef struct lfs_dir { } lfs_dir_t; typedef struct lfsr_dir { - lfsr_openedmdir_t mdir; + lfsr_openedmdir_t m; lfs_size_t did; lfs_ssize_t dstart_mid; lfs_ssize_t dstart_rid; diff --git a/tests/t3_mtree.toml b/tests/t3_mtree.toml index 9a490f24..bfa11a05 100644 --- a/tests/t3_mtree.toml +++ b/tests/t3_mtree.toml @@ -23,7 +23,7 @@ code = ''' lfs_alloc_ack(&lfs); for (lfs_size_t i = 0; i < N; i++) { - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(i), 0, &alphas[i % 26], 1))) => 0; } @@ -63,9 +63,9 @@ code = ''' for (lfs_size_t i = 0; i < N; i++) { // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(i), 0, &alphas[i % 26], 1))) => 0; } @@ -104,7 +104,7 @@ code = ''' lfs_alloc_ack(&lfs); for (lfs_size_t i = 0; i < N; i++) { - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, &alphas[i % 26], 1))) => 0; uint8_t buffer[4]; @@ -146,28 +146,28 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // prepare mroot with a large attr so the next entry can not fit uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // create a large entry that needs to be uninlined (but not split!) memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdir was unininlined correctly assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -176,8 +176,8 @@ code = ''' // assert that our entry is still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -192,7 +192,7 @@ code = ''' // assert mdir was unininlined correctly assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -200,8 +200,8 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -221,38 +221,38 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create 2 large entries that needs to be uninlined and split uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdirs were unininlined and split assert(lfsr_mtree_weight(&lfs) == 2); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our entries are still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 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, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -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); @@ -266,17 +266,17 @@ code = ''' // assert mdirs were unininlined and split assert(lfsr_mtree_weight(&lfs) == 2); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 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, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -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); @@ -295,45 +295,45 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create an uninlined mdir uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdir was unininlined correctly assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // now add another large entry to the mdir, forcing a split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mdir to compact - mdir.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){1}, NULL, 0) => 0; + mdir.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &mdir, NULL, 0) => 0; // assert mdir was split correctly assert(lfsr_mtree_weight(&lfs) == 2); // assert mroot still has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -341,14 +341,14 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 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, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -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); @@ -361,7 +361,7 @@ code = ''' // assert mdir was split correctly assert(lfsr_mtree_weight(&lfs) == 2); // assert mroot still has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -369,14 +369,14 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 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, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -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); @@ -397,30 +397,30 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create entries lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, -1, &mdir) => 0; - lfs_ssize_t rid = 0; + mdir.rid = 0; for (lfs_size_t i = 0; i < N; i++) { // force a compaction? if (FORCE_COMPACTION) { - mdir.rbyd.off = cfg->block_size; - lfs.mroot.rbyd.off = cfg->block_size; + mdir.m.rbyd.off = cfg->block_size; + lfs.mroot.m.rbyd.off = cfg->block_size; } - lfsr_mdir_commit(&lfs, &mdir, &rid, LFSR_ATTRS( - LFSR_ATTR(rid, INLINED, +1, &alphas[i % 26], 1))) => 0; + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( + LFSR_ATTR(mdir.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); - rid += 1; + mdir.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, &mdir) => 0; - for (lfs_ssize_t rid = 0; - rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); - rid++) { + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + for (mdir.rid = 0; + mdir.rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); + mdir.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.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, &mdir) => 0; - for (lfs_ssize_t rid = 0; - rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); - rid++) { + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + for (mdir.rid = 0; + mdir.rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); + mdir.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -484,7 +484,7 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // at least keep track of the number of entries we expect @@ -498,23 +498,23 @@ code = ''' : (lfs_ssize_t)(TEST_PRNG(&prng) % lfsr_mtree_weight(&lfs)); // fetch mdir lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, &mdir) => 0; + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; // choose a pseudo-random rid - lfs_ssize_t rid = TEST_PRNG(&prng) % (lfsr_mdir_weight(&mdir)+1); + mdir.rid = TEST_PRNG(&prng) % (lfsr_mdir_weight(&mdir)+1); // force a compaction? if (FORCE_COMPACTION) { - mdir.rbyd.off = cfg->block_size; - lfs.mroot.rbyd.off = cfg->block_size; + mdir.m.rbyd.off = cfg->block_size; + lfs.mroot.m.rbyd.off = cfg->block_size; } // add to rbyd, potentially splitting the mdir - lfsr_mdir_commit(&lfs, &mdir, &rid, LFSR_ATTRS( - LFSR_ATTR(rid, INLINED, +1, &alphas[i % 26], 1))) => 0; + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( + LFSR_ATTR(mdir.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, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.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, &mdir) => 0; - for (lfs_ssize_t rid = 0; - rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); - rid++) { + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + for (mdir.rid = 0; + mdir.rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); + mdir.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.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, &mdir) => 0; - for (lfs_ssize_t rid = 0; - rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); - rid++) { + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + for (mdir.rid = 0; + mdir.rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); + mdir.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -591,40 +591,40 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create an uninlined mdir uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdir was unininlined correctly assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // remove the entry, forcing the mdir to be dropped lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 0); // assert mroot still has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -640,7 +640,7 @@ code = ''' // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 0); // assert mroot still has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -661,43 +661,43 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create an uninlined mdir uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdir was unininlined correctly assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // remove the entry, forcing the mdir to be dropped lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); // force mdir to compact while we're removing - mdir.rbyd.off = BLOCK_SIZE; + mdir.m.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 0); // assert mroot still has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -713,7 +713,7 @@ code = ''' // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 0); // assert mroot still has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -734,30 +734,30 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create an uninlined mdir uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; // remove the entry as we compact, forcing the mdir to be dropped - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 0); // assert mroot has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -773,7 +773,7 @@ code = ''' // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 0); // assert mroot has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -794,36 +794,36 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create an mdir that needs to be split uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; // remove the left entry as we compact, forcing the left // mdir to be dropped - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that one entry is still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -838,11 +838,11 @@ code = ''' // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that one entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -862,36 +862,36 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create an mdir that needs to be split uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; // remove the right entry as we compact, forcing the right mdir // to be dropped - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(1, UNR, -1, NULL, 0))) => 0; // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that one entry is still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -906,11 +906,11 @@ code = ''' // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that one entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -930,31 +930,31 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create an mdir that needs to be split uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; // remove both entries as we compact, forcing both mdirs to be dropped - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0), LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 0); // assert mroot has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); lfsr_unmount(&lfs) => 0; @@ -965,7 +965,7 @@ code = ''' // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 0); // assert mroot has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); lfsr_unmount(&lfs) => 0; ''' @@ -981,49 +981,49 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create an uninlined mdir uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdir was unininlined correctly assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // now add another large entry to the mdir, forcing a split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mdir to compact - mdir.rbyd.off = BLOCK_SIZE; + mdir.m.rbyd.off = BLOCK_SIZE; // remove the left entry as we compact, forcing the left // mdir to be dropped - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){0}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -1031,8 +1031,8 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that one entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -1047,7 +1047,7 @@ code = ''' // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -1055,8 +1055,8 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that one entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -1076,49 +1076,49 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create an uninlined mdir uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdir was unininlined correctly assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // now add another large entry to the mdir, forcing a split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mdir to compact - mdir.rbyd.off = BLOCK_SIZE; + mdir.m.rbyd.off = BLOCK_SIZE; // remove the right entry as we compact, forcing the right // mdir to be dropped - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(1, UNR, -1, NULL, 0))) => 0; // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -1126,8 +1126,8 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that one entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -1142,7 +1142,7 @@ code = ''' // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -1150,8 +1150,8 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that one entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -1171,49 +1171,49 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create an uninlined mdir uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdir was unininlined correctly assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // now add another large entry to the mdir, forcing a split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mdir to compact - mdir.rbyd.off = BLOCK_SIZE; + mdir.m.rbyd.off = BLOCK_SIZE; // remove both entries as we compact, forcing both mdirs to be dropped - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0), LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 0); // assert mroot has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -1229,7 +1229,7 @@ code = ''' // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 0); // assert mroot has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -1253,42 +1253,42 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create entries lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, -1, &mdir) => 0; - lfs_ssize_t rid = 0; + mdir.rid = 0; for (lfs_size_t i = 0; i < N; i++) { - lfsr_mdir_commit(&lfs, &mdir, &rid, LFSR_ATTRS( - LFSR_ATTR(rid, INLINED, +1, &alphas[i % 26], 1))) => 0; + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( + LFSR_ATTR(mdir.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); - rid += 1; + mdir.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, &mdir) => 0; + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; // drop should make sure we never have empty mdirs - assert(mdir.mid == -1 || mdir.rbyd.weight > 0); + assert(mdir.mid == -1 || mdir.m.rbyd.weight > 0); // force a compaction? if (FORCE_COMPACTION) { - mdir.rbyd.off = cfg->block_size; - lfs.mroot.rbyd.off = cfg->block_size; + mdir.m.rbyd.off = cfg->block_size; + lfs.mroot.m.rbyd.off = cfg->block_size; } - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){0}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; } @@ -1298,12 +1298,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, &mdir) => 0; - for (lfs_ssize_t rid = 0; - rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); - rid++) { + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + for (mdir.rid = 0; + mdir.rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); + mdir.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.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, &mdir) => 0; - for (lfs_ssize_t rid = 0; - rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); - rid++) { + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + for (mdir.rid = 0; + mdir.rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); + mdir.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -1352,25 +1352,25 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; for (lfs_size_t cycle = 0; cycle < CYCLES; cycle++) { // create entries lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, -1, &mdir) => 0; - lfs_ssize_t rid = 0; + mdir.rid = 0; for (lfs_size_t i = 0; i < N; i++) { - lfsr_mdir_commit(&lfs, &mdir, &rid, LFSR_ATTRS( - LFSR_ATTR(rid, INLINED, +1, &alphas[i % 26], 1))) => 0; + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( + LFSR_ATTR(mdir.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); - rid += 1; + mdir.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, &mdir) => 0; - for (lfs_ssize_t rid = 0; - rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); - rid++) { + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + for (mdir.rid = 0; + mdir.rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); + mdir.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -1396,18 +1396,18 @@ 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, &mdir) => 0; + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; // drop should make sure we never have empty mdirs - assert(mdir.mid == -1 || mdir.rbyd.weight > 0); + assert(mdir.mid == -1 || mdir.m.rbyd.weight > 0); // force a compaction? if (FORCE_COMPACTION) { - mdir.rbyd.off = cfg->block_size; - lfs.mroot.rbyd.off = cfg->block_size; + mdir.m.rbyd.off = cfg->block_size; + lfs.mroot.m.rbyd.off = cfg->block_size; } - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){0}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; } @@ -1440,7 +1440,7 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // at least keep track of the number of entries we expect @@ -1454,30 +1454,30 @@ code = ''' : (lfs_ssize_t)(TEST_PRNG(&prng) % lfsr_mtree_weight(&lfs)); // fetch mdir lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, &mdir) => 0; + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; // choose a pseudo-random rid - lfs_ssize_t rid = TEST_PRNG(&prng) % (lfsr_mdir_weight(&mdir)+1); + mdir.rid = TEST_PRNG(&prng) % (lfsr_mdir_weight(&mdir)+1); // choose to create or delete - uint8_t op = (lfs_size_t)rid == lfsr_mdir_weight(&mdir) + uint8_t op = (lfs_size_t)mdir.rid == lfsr_mdir_weight(&mdir) ? 0 : TEST_PRNG(&prng) % 2; // force a compaction? if (FORCE_COMPACTION) { - mdir.rbyd.off = cfg->block_size; - lfs.mroot.rbyd.off = cfg->block_size; + mdir.m.rbyd.off = cfg->block_size; + lfs.mroot.m.rbyd.off = cfg->block_size; } // create if (op == 0) { // add to rbyd, potentially splitting the mdir - lfsr_mdir_commit(&lfs, &mdir, &rid, LFSR_ATTRS( - LFSR_ATTR(rid, INLINED, +1, + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( + LFSR_ATTR(mdir.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, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); @@ -1485,8 +1485,8 @@ code = ''' // delete } else { - lfsr_mdir_commit(&lfs, &mdir, &rid, LFSR_ATTRS( - LFSR_ATTR(rid, UNR, -1, NULL, 0))) => 0; + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( + LFSR_ATTR(mdir.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, &mdir) => 0; + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; // drop should make sure we never have empty mdirs - assert(mdir.mid == -1 || mdir.rbyd.weight > 0); + assert(mdir.mid == -1 || mdir.m.rbyd.weight > 0); - for (lfs_ssize_t rid = 0; - rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); - rid++) { + for (mdir.rid = 0; + mdir.rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); + mdir.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.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, &mdir) => 0; + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; // drop should make sure we never have empty mdirs - assert(mdir.mid == -1 || mdir.rbyd.weight > 0); + assert(mdir.mid == -1 || mdir.m.rbyd.weight > 0); - for (lfs_ssize_t rid = 0; - rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); - rid++) { + for (mdir.rid = 0; + mdir.rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); + mdir.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -1572,41 +1572,41 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // prepare mroot with a large attr so the next entry can not fit uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // create a large entry that needs to be uninlined (but not split!) memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mtree has one mdir assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // force mdir to compact twice, this should relocate lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_t old_mdir = mdir; - mdir.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){0}, NULL, 0) => 0; - mdir.rbyd.off = BLOCK_SIZE; + mdir.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &mdir, NULL, 0) => 0; + mdir.m.rbyd.off = BLOCK_SIZE; memset(buffer, alphas[2 % 26], SIZE); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){0}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(0, INLINED, 0, buffer, SIZE))) => 0; // assert we relocated @@ -1618,8 +1618,8 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -1634,7 +1634,7 @@ code = ''' // assert mtree has one mdir assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert we relocated assert(lfsr_mdir_cmp(&old_mdir, &mdir) != 0); @@ -1645,8 +1645,8 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -1668,54 +1668,54 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create 2 large entries that needs to be uninlined and split uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdirs were unininlined and split assert(lfsr_mtree_weight(&lfs) == 2); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // force mdir to compact twice, this should relocate lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_t old_mdir = mdir; - mdir.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){0}, NULL, 0) => 0; - mdir.rbyd.off = BLOCK_SIZE; + mdir.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &mdir, NULL, 0) => 0; + mdir.m.rbyd.off = BLOCK_SIZE; memset(buffer, alphas[2 % 26], SIZE); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){0}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(0, INLINED, 0, buffer, SIZE))) => 0; // assert we relocated assert(lfsr_mdir_cmp(&old_mdir, &mdir) != 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 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, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -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); @@ -1729,20 +1729,20 @@ code = ''' // assert mdirs were unininlined and split assert(lfsr_mtree_weight(&lfs) == 2); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert we relocated assert(lfsr_mdir_cmp(&old_mdir, &mdir) != 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 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, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -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); @@ -1763,54 +1763,54 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create 2 large entries that needs to be uninlined and split uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdirs were unininlined and split assert(lfsr_mtree_weight(&lfs) == 2); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // force mdir to compact twice, this should relocate lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 1, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_t old_mdir = mdir; - mdir.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){0}, NULL, 0) => 0; - mdir.rbyd.off = BLOCK_SIZE; + mdir.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &mdir, NULL, 0) => 0; + mdir.m.rbyd.off = BLOCK_SIZE; memset(buffer, alphas[2 % 26], SIZE); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){0}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(0, INLINED, 0, buffer, SIZE))) => 0; // assert we relocated assert(lfsr_mdir_cmp(&old_mdir, &mdir) != 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 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, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -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); @@ -1824,20 +1824,20 @@ code = ''' // assert mdirs were unininlined and split assert(lfsr_mtree_weight(&lfs) == 2); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert we relocated assert(lfsr_mdir_cmp(&old_mdir, &mdir) != 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 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, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -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); @@ -1858,23 +1858,23 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // prepare mroot with an attr uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // force mroot to compact twice, this should extend the mroot lfsr_mdir_t old_mroot = lfs.mroot; - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; - lfs.mroot.rbyd.off = BLOCK_SIZE; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // assert we relocated @@ -1918,25 +1918,25 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // prepare mroot with an attr uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // force mroot to compact 2x2 times, this should extend the mroot twice lfsr_mdir_t old_mroot = lfs.mroot; for (int i = 0; i < 4; i++) { - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; } - lfs.mroot.rbyd.off = BLOCK_SIZE; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // assert we relocated @@ -1977,22 +1977,22 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // prepare mroot with an attr uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // force mroot to compact twice, this should extend the mroot lfsr_mdir_t old_mroot = lfs.mroot; - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert we relocated assert(lfsr_mdir_cmp(&old_mroot, &lfs.mroot) != 0); @@ -2000,11 +2000,11 @@ code = ''' // force mroot to compact twice again, this should relocate the mroot old_mroot = lfs.mroot; - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; - lfs.mroot.rbyd.off = BLOCK_SIZE; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // assert we relocated @@ -2045,46 +2045,46 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // prepare mroot with a large attr so the next entry can not fit uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // create a large entry that needs to be uninlined (but not split!) memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mtree has one mdir assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // setup mroot to need to compact, this should trigger a relocation when // we relocate the mdir below - lfs.mroot.rbyd.off = BLOCK_SIZE; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; lfsr_mdir_t old_mroot = lfs.mroot; // force mdir to compact twice, this should relocate lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_t old_mdir = mdir; - mdir.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){0}, NULL, 0) => 0; - mdir.rbyd.off = BLOCK_SIZE; + mdir.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &mdir, NULL, 0) => 0; + mdir.m.rbyd.off = BLOCK_SIZE; memset(buffer, alphas[2 % 26], SIZE); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){0}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(0, INLINED, 0, buffer, SIZE))) => 0; // assert we relocated our mdir @@ -2099,8 +2099,8 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -2115,7 +2115,7 @@ code = ''' // assert mtree has one mdir assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert we relocated our mdir assert(lfsr_mdir_cmp(&old_mdir, &mdir) != 0); @@ -2129,8 +2129,8 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -2152,50 +2152,50 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create an uninlined mdir uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdir was unininlined correctly assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // setup mroot to need to compact, this should trigger a relocation when // we relocate the mdir below - lfs.mroot.rbyd.off = BLOCK_SIZE; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; lfsr_mdir_t old_mroot = lfs.mroot; // now add another large entry to the mdir, forcing a split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mdir to compact - mdir.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){1}, NULL, 0) => 0; + mdir.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &mdir, NULL, 0) => 0; // assert mdir was split correctly assert(lfsr_mtree_weight(&lfs) == 2); // assert mroot still has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert we relocated our mroot assert(lfsr_mdir_cmp(&old_mroot, &lfs.mroot) != 0); @@ -2206,14 +2206,14 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 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, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -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); @@ -2227,7 +2227,7 @@ code = ''' // assert mdir was split correctly assert(lfsr_mtree_weight(&lfs) == 2); // assert mroot still has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert we relocated our mroot assert(lfsr_mdir_cmp(&old_mroot, &lfs.mroot) != 0); @@ -2238,14 +2238,14 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 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, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -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); @@ -2266,45 +2266,45 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create an uninlined mdir uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdir was unininlined correctly assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // setup mroot to need to compact, this should trigger a relocation when // we relocate the mdir below - lfs.mroot.rbyd.off = BLOCK_SIZE; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; lfsr_mdir_t old_mroot = lfs.mroot; // remove the entry, forcing the mdir to be dropped lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){0}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 0); // assert mroot still has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert we relocated our mroot assert(lfsr_mdir_cmp(&old_mroot, &lfs.mroot) != 0); @@ -2323,7 +2323,7 @@ code = ''' // assert mdir was dropped assert(lfsr_mtree_weight(&lfs) == 0); // assert mroot still has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert we relocated our mroot assert(lfsr_mdir_cmp(&old_mroot, &lfs.mroot) != 0); @@ -2349,34 +2349,34 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // force mroot to compact once, so the second compact below will trigger // a relocation - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // prepare mroot with a large attr so the next entry can not fit uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // create a large entry that needs to be uninlined (but not split!) memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact, this should trigger a relocation lfsr_mdir_t old_mroot = lfs.mroot; - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdir was unininlined correctly assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert we relocated our mroot assert(lfsr_mdir_cmp(&old_mroot, &lfs.mroot) != 0); @@ -2388,8 +2388,8 @@ code = ''' // assert that our entry is still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -2404,7 +2404,7 @@ code = ''' // assert mdir was unininlined correctly assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert we relocated our mroot assert(lfsr_mdir_cmp(&old_mroot, &lfs.mroot) != 0); @@ -2415,8 +2415,8 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -2438,47 +2438,47 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // force mroot to compact once, so the second compact below will trigger // a relocation - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // create 2 large entries that needs to be uninlined and split uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact, this should trigger a relocation lfsr_mdir_t old_mroot = lfs.mroot; - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdirs were unininlined and split assert(lfsr_mtree_weight(&lfs) == 2); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert we relocated our mroot assert(lfsr_mdir_cmp(&old_mroot, &lfs.mroot) != 0); // assert that our entries are still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 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, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -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); @@ -2492,20 +2492,20 @@ code = ''' // assert mdirs were unininlined and split assert(lfsr_mtree_weight(&lfs) == 2); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert we relocated our mroot assert(lfsr_mdir_cmp(&old_mroot, &lfs.mroot) != 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 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, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -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); @@ -2528,7 +2528,7 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // at least keep track of the number of entries we expect @@ -2542,30 +2542,30 @@ code = ''' : (lfs_ssize_t)(TEST_PRNG(&prng) % lfsr_mtree_weight(&lfs)); // fetch mdir lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, &mdir) => 0; + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; // choose a pseudo-random rid - lfs_ssize_t rid = TEST_PRNG(&prng) % (lfsr_mdir_weight(&mdir)+1); + mdir.rid = TEST_PRNG(&prng) % (lfsr_mdir_weight(&mdir)+1); // choose to create or delete - uint8_t op = (lfs_size_t)rid == lfsr_mdir_weight(&mdir) + uint8_t op = (lfs_size_t)mdir.rid == lfsr_mdir_weight(&mdir) ? 0 : TEST_PRNG(&prng) % 3; // force a compaction? if (FORCE_COMPACTION) { - mdir.rbyd.off = cfg->block_size; - lfs.mroot.rbyd.off = cfg->block_size; + mdir.m.rbyd.off = cfg->block_size; + lfs.mroot.m.rbyd.off = cfg->block_size; } // create if (op == 0) { // add to rbyd - lfsr_mdir_commit(&lfs, &mdir, &rid, LFSR_ATTRS( - LFSR_ATTR(rid, INLINED, +1, + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( + LFSR_ATTR(mdir.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, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); @@ -2574,20 +2574,20 @@ code = ''' // update } else if (op == 1) { // update rbyd - lfsr_mdir_commit(&lfs, &mdir, &rid, LFSR_ATTRS( - LFSR_ATTR(rid, INLINED, 0, + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( + LFSR_ATTR(mdir.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, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); // delete } else { - lfsr_mdir_commit(&lfs, &mdir, &rid, LFSR_ATTRS( - LFSR_ATTR(rid, UNR, -1, NULL, 0))) => 0; + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( + LFSR_ATTR(mdir.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, &mdir) => 0; + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; // drop should make sure we never have empty mdirs - assert(mdir.mid == -1 || mdir.rbyd.weight > 0); + assert(mdir.mid == -1 || mdir.m.rbyd.weight > 0); - for (lfs_ssize_t rid = 0; - rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); - rid++) { + for (mdir.rid = 0; + mdir.rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); + mdir.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.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, &mdir) => 0; + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; // drop should make sure we never have empty mdirs - assert(mdir.mid == -1 || mdir.rbyd.weight > 0); + assert(mdir.mid == -1 || mdir.m.rbyd.weight > 0); - for (lfs_ssize_t rid = 0; - rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); - rid++) { + for (mdir.rid = 0; + mdir.rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); + mdir.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -2668,27 +2668,29 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // setup our neighbors - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, &alphas[0 % 26], 1), LFSR_ATTR(1, INLINED, +1, &alphas[1 % 26], 1))) => 0; // this test only works if these all fit in the mroot assert(lfsr_mtree_isinlined(&lfs)); - lfsr_openedmdir_t left_neighbor = {.rid=0, .mdir=lfs.mroot}; - lfsr_openedmdir_t right_neighbor = {.rid=1, .mdir=lfs.mroot}; + lfsr_openedmdir_t left_neighbor = { + .mdir={.mid=-1, .rid=0, .m=lfs.mroot.m}}; + lfsr_openedmdir_t right_neighbor = { + .mdir={.mid=-1, .rid=1, .m=lfs.mroot.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); // insert a new entry, this should update our neighbors - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, &alphas[2 % 26], 1))) => 0; // assert that our entry is still in the mtree - assert(lfs.mroot.rbyd.weight == 3); + assert(lfs.mroot.m.rbyd.weight == 3); uint8_t buffer[1]; lfsr_mdir_get(&lfs, &lfs.mroot, 1, LFSR_TAG_INLINED, @@ -2696,12 +2698,14 @@ code = ''' assert(memcmp(buffer, &alphas[2 % 26], 1) == 0); // assert that our neighbors were updated correctly - assert(left_neighbor.rid == 0); assert(left_neighbor.mdir.mid == -1); - assert(memcmp(&left_neighbor.mdir, &lfs.mroot, sizeof(lfsr_mdir_t)) == 0); - assert(right_neighbor.rid == 2); + assert(left_neighbor.mdir.rid == 0); + assert(memcmp(&left_neighbor.mdir.m, &lfs.mroot.m, + sizeof(lfs.mroot.m)) == 0); assert(right_neighbor.mdir.mid == -1); - assert(memcmp(&right_neighbor.mdir, &lfs.mroot, sizeof(lfsr_mdir_t)) == 0); + assert(right_neighbor.mdir.rid == 2); + assert(memcmp(&right_neighbor.mdir.m, &lfs.mroot.m, + sizeof(lfs.mroot.m)) == 0); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -2717,33 +2721,36 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // setup our neighbors - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, &alphas[0 % 26], 1), LFSR_ATTR(1, INLINED, +1, &alphas[1 % 26], 1))) => 0; // this test only works if these all fit in the mroot assert(lfsr_mtree_isinlined(&lfs)); - lfsr_openedmdir_t left_neighbor = {.rid=0, .mdir=lfs.mroot}; - lfsr_openedmdir_t right_neighbor = {.rid=1, .mdir=lfs.mroot}; + lfsr_openedmdir_t left_neighbor = { + .mdir={.mid=-1, .rid=0, .m=lfs.mroot.m}}; + lfsr_openedmdir_t right_neighbor = { + .mdir={.mid=-1, .rid=1, .m=lfs.mroot.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); // try removing our left entry - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // assert that an entry was removed - assert(lfs.mroot.rbyd.weight == 1); + assert(lfs.mroot.m.rbyd.weight == 1); // assert that our neighbors were updated correctly assert(left_neighbor.mdir.mid == LFSR_MID_RM); - assert(right_neighbor.rid == 0); assert(right_neighbor.mdir.mid == -1); - assert(memcmp(&right_neighbor.mdir, &lfs.mroot, sizeof(lfsr_mdir_t)) == 0); + assert(right_neighbor.mdir.rid == 0); + assert(memcmp(&right_neighbor.mdir.m, &lfs.mroot.m, + sizeof(lfs.mroot.m)) == 0); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -2759,32 +2766,35 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // setup our neighbors - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, &alphas[0 % 26], 1), LFSR_ATTR(1, INLINED, +1, &alphas[1 % 26], 1))) => 0; // this test only works if these all fit in the mroot assert(lfsr_mtree_isinlined(&lfs)); - lfsr_openedmdir_t left_neighbor = {.rid=0, .mdir=lfs.mroot}; - lfsr_openedmdir_t right_neighbor = {.rid=1, .mdir=lfs.mroot}; + lfsr_openedmdir_t left_neighbor = { + .mdir={.mid=-1, .rid=0, .m=lfs.mroot.m}}; + lfsr_openedmdir_t right_neighbor = { + .mdir={.mid=-1, .rid=1, .m=lfs.mroot.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); // try removing our left entry - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(1, UNR, -1, NULL, 0))) => 0; // assert that an entry was removed - assert(lfs.mroot.rbyd.weight == 1); + assert(lfs.mroot.m.rbyd.weight == 1); // assert that our neighbors were updated correctly - assert(left_neighbor.rid == 0); assert(left_neighbor.mdir.mid == -1); - assert(memcmp(&left_neighbor.mdir, &lfs.mroot, sizeof(lfsr_mdir_t)) == 0); + assert(left_neighbor.mdir.rid == 0); + assert(memcmp(&left_neighbor.mdir.m, &lfs.mroot.m, + sizeof(lfs.mroot.m)) == 0); assert(right_neighbor.mdir.mid == LFSR_MID_RM); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); @@ -2803,40 +2813,42 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // setup our neighbors - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, &alphas[0 % 26], 1), LFSR_ATTR(1, INLINED, +1, &alphas[1 % 26], 1))) => 0; // this test only works if these all fit in the mroot assert(lfsr_mtree_isinlined(&lfs)); - lfsr_openedmdir_t left_neighbor = {.rid=0, .mdir=lfs.mroot}; - lfsr_openedmdir_t right_neighbor = {.rid=1, .mdir=lfs.mroot}; + lfsr_openedmdir_t left_neighbor = { + .mdir={.mid=-1, .rid=0, .m=lfs.mroot.m}}; + lfsr_openedmdir_t right_neighbor = { + .mdir={.mid=-1, .rid=1, .m=lfs.mroot.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); // prepare mroot with a large attr so the next entry can not fit uint8_t buffer[SIZE]; memset(buffer, alphas[2 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // create a large entry that needs to be uninlined (but not split!) memset(buffer, alphas[3 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdir was unininlined correctly assert(lfsr_mtree_weight(&lfs) == 2); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -2845,8 +2857,8 @@ code = ''' // assert that our entry is still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 2); + lfsr_mtree_lookup(&lfs, 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); @@ -2854,16 +2866,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, &msibling) => 0; - assert(msibling.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -1, &msibling) => 0; + assert(msibling.m.rbyd.weight == 1); // assert that our neighbors were updated correctly - assert(left_neighbor.rid == 0); assert(left_neighbor.mdir.mid == 0); - assert(memcmp(&left_neighbor.mdir, &mdir, sizeof(lfsr_mdir_t)) == 0); - assert(right_neighbor.rid == 0); + assert(left_neighbor.mdir.rid == 0); + assert(memcmp(&left_neighbor.mdir.m, &mdir.m, + sizeof(mdir.m)) == 0); assert(right_neighbor.mdir.mid == 1); - assert(memcmp(&right_neighbor.mdir, &msibling, sizeof(lfsr_mdir_t)) == 0); + assert(right_neighbor.mdir.rid == 0); + assert(memcmp(&right_neighbor.mdir.m, &msibling.m, + sizeof(msibling.m)) == 0); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -2881,62 +2895,66 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // setup our neighbors - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, &alphas[0 % 26], 1), LFSR_ATTR(1, INLINED, +1, &alphas[1 % 26], 1))) => 0; // this test only works if these all fit in the mroot assert(lfsr_mtree_isinlined(&lfs)); - lfsr_openedmdir_t left_neighbor = {.rid=0, .mdir=lfs.mroot}; - lfsr_openedmdir_t right_neighbor = {.rid=1, .mdir=lfs.mroot}; + lfsr_openedmdir_t left_neighbor = { + .mdir={.mid=-1, .rid=0, .m=lfs.mroot.m}}; + lfsr_openedmdir_t right_neighbor = { + .mdir={.mid=-1, .rid=1, .m=lfs.mroot.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); // create 2 large entries that needs to be uninlined and split uint8_t buffer[SIZE]; memset(buffer, alphas[2 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; memset(buffer, alphas[3 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(2, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdirs were unininlined and split assert(lfsr_mtree_weight(&lfs) == 2); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our entries are still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 2); + lfsr_mtree_lookup(&lfs, 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, &msibling) => 0; - assert(msibling.rbyd.weight == 2); + lfsr_mtree_lookup(&lfs, 1, -1, &msibling) => 0; + assert(msibling.m.rbyd.weight == 2); lfsr_mdir_get(&lfs, &msibling, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[3 % 26], 1) == 0); // assert that our neighbors were updated correctly - assert(left_neighbor.rid == 0); assert(left_neighbor.mdir.mid == 0); - assert(memcmp(&left_neighbor.mdir, &mdir, sizeof(lfsr_mdir_t)) == 0); - assert(right_neighbor.rid == 1); + assert(left_neighbor.mdir.rid == 0); + assert(memcmp(&left_neighbor.mdir.m, &mdir.m, + sizeof(mdir.m)) == 0); assert(right_neighbor.mdir.mid == 1); - assert(memcmp(&right_neighbor.mdir, &msibling, sizeof(lfsr_mdir_t)) == 0); + assert(right_neighbor.mdir.rid == 1); + assert(memcmp(&right_neighbor.mdir.m, &msibling.m, + sizeof(msibling.m)) == 0); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -2954,61 +2972,63 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create an uninlined mdir uint8_t buffer[SIZE]; memset(buffer, alphas[2 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; memset(buffer, alphas[3 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdir was unininlined correctly assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // setup our neighbors // // 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, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){0}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, &alphas[0 % 26], 1), LFSR_ATTR(2, INLINED, +1, &alphas[1 % 26], 1))) => 0; // this test only works if these all fit in the mdir assert(lfsr_mtree_weight(&lfs) == 1); - assert(mdir.rbyd.weight == 3); + assert(mdir.m.rbyd.weight == 3); - lfsr_openedmdir_t left_neighbor = {.rid=0, .mdir=mdir}; - lfsr_openedmdir_t right_neighbor = {.rid=2, .mdir=mdir}; + lfsr_openedmdir_t left_neighbor = { + .mdir={.mid=mdir.mid, .rid=0, .m=mdir.m}}; + lfsr_openedmdir_t right_neighbor = { + .mdir={.mid=mdir.mid, .rid=2, .m=mdir.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); // now add another large entry to the mdir, forcing a split memset(buffer, alphas[4 % 26], SIZE); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){2}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(2, INLINED, +1, buffer, SIZE))) => 0; // force mdir to compact - mdir.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){2}, NULL, 0) => 0; + mdir.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &mdir, NULL, 0) => 0; // assert mdir was split correctly assert(lfsr_mtree_weight(&lfs) == 2); // assert mroot still has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -3016,26 +3036,28 @@ code = ''' assert(memcmp(buffer, &alphas[2 % 26], 1) == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 2); + lfsr_mtree_lookup(&lfs, 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, &msibling) => 0; - assert(msibling.rbyd.weight == 2); + lfsr_mtree_lookup(&lfs, 1, -1, &msibling) => 0; + assert(msibling.m.rbyd.weight == 2); lfsr_mdir_get(&lfs, &msibling, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[4 % 26], 1) == 0); // assert that our neighbors were updated correctly - assert(left_neighbor.rid == 0); assert(left_neighbor.mdir.mid == 0); - assert(memcmp(&left_neighbor.mdir, &mdir, sizeof(lfsr_mdir_t)) == 0); - assert(right_neighbor.rid == 1); + assert(left_neighbor.mdir.rid == 0); + assert(memcmp(&left_neighbor.mdir.m, &mdir.m, + sizeof(mdir.m)) == 0); assert(right_neighbor.mdir.mid == 1); - assert(memcmp(&right_neighbor.mdir, &msibling, sizeof(lfsr_mdir_t)) == 0); + assert(right_neighbor.mdir.rid == 1); + assert(memcmp(&right_neighbor.mdir.m, &msibling.m, + sizeof(msibling.m)) == 0); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -3055,35 +3077,37 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // setup our neighbors - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, &alphas[0 % 26], 1), LFSR_ATTR(1, INLINED, +1, &alphas[1 % 26], 1))) => 0; // this test only works if these all fit in the mroot assert(lfsr_mtree_isinlined(&lfs)); - lfsr_openedmdir_t left_neighbor = {.rid=0, .mdir=lfs.mroot}; - lfsr_openedmdir_t right_neighbor = {.rid=1, .mdir=lfs.mroot}; + lfsr_openedmdir_t left_neighbor = { + .mdir={.mid=-1, .rid=0, .m=lfs.mroot.m}}; + lfsr_openedmdir_t right_neighbor = { + .mdir={.mid=-1, .rid=1, .m=lfs.mroot.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); // prepare mroot with an attr uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // force mroot to compact twice, this should extend the mroot lfsr_mdir_t old_mroot = lfs.mroot; - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; - lfs.mroot.rbyd.off = BLOCK_SIZE; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // assert we relocated @@ -3095,12 +3119,14 @@ code = ''' assert(memcmp(buffer, &alphas[1 % 26], 1) == 0); // assert that our neighbors were updated correctly - assert(left_neighbor.rid == 0); assert(left_neighbor.mdir.mid == -1); - assert(memcmp(&left_neighbor.mdir, &lfs.mroot, sizeof(lfsr_mdir_t)) == 0); - assert(right_neighbor.rid == 1); + assert(left_neighbor.mdir.rid == 0); + assert(memcmp(&left_neighbor.mdir.m, &lfs.mroot.m, + sizeof(lfs.mroot.m)) == 0); assert(right_neighbor.mdir.mid == -1); - assert(memcmp(&right_neighbor.mdir, &lfs.mroot, sizeof(lfsr_mdir_t)) == 0); + assert(right_neighbor.mdir.rid == 1); + assert(memcmp(&right_neighbor.mdir.m, &lfs.mroot.m, + sizeof(lfs.mroot.m)) == 0); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -3120,56 +3146,58 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create an uninlined mdir uint8_t buffer[SIZE]; memset(buffer, alphas[2 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; memset(buffer, alphas[3 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdir was unininlined correctly assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // setup our neighbors // // 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, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){0}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, &alphas[0 % 26], 1), LFSR_ATTR(2, INLINED, +1, &alphas[1 % 26], 1))) => 0; // this test only works if these all fit in the mdir assert(lfsr_mtree_weight(&lfs) == 1); - assert(mdir.rbyd.weight == 3); + assert(mdir.m.rbyd.weight == 3); - lfsr_openedmdir_t left_neighbor = {.rid=0, .mdir=mdir}; - lfsr_openedmdir_t right_neighbor = {.rid=2, .mdir=mdir}; + lfsr_openedmdir_t left_neighbor = { + .mdir={.mid=mdir.mid, .rid=0, .m=mdir.m}}; + lfsr_openedmdir_t right_neighbor = { + .mdir={.mid=mdir.mid, .rid=2, .m=mdir.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); // force mdir to compact twice, this should relocate lfsr_mdir_t old_mdir = mdir; - mdir.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){0}, NULL, 0) => 0; - mdir.rbyd.off = BLOCK_SIZE; + mdir.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &mdir, NULL, 0) => 0; + mdir.m.rbyd.off = BLOCK_SIZE; memset(buffer, alphas[4 % 26], SIZE); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){0}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(1, INLINED, 0, buffer, SIZE))) => 0; // assert we relocated @@ -3181,20 +3209,20 @@ code = ''' assert(memcmp(buffer, &alphas[2 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 3); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 3); lfsr_mdir_get(&lfs, &mdir, 1, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[4 % 26], 1) == 0); // assert that our neighbors were updated correctly - assert(left_neighbor.rid == 0); assert(left_neighbor.mdir.mid == 0); - assert(memcmp(&left_neighbor.mdir, &mdir, sizeof(lfsr_mdir_t)) == 0); - assert(right_neighbor.rid == 2); + assert(left_neighbor.mdir.rid == 0); + assert(memcmp(&left_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); assert(right_neighbor.mdir.mid == 0); - assert(memcmp(&right_neighbor.mdir, &mdir, sizeof(lfsr_mdir_t)) == 0); + assert(right_neighbor.mdir.rid == 2); + assert(memcmp(&right_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -3214,7 +3242,7 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; //// create a situation where we have 3 mdirs in our tree @@ -3222,30 +3250,30 @@ code = ''' // first force mroot to uninlined+split uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // we should now have 2 mdirs assert(lfsr_mtree_weight(&lfs) == 2); // now force one of our siblings to split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 1, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mdir to compact - mdir.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){-1}, NULL, 0) => 0; + mdir.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &mdir, NULL, 0) => 0; // we should now have 3 mdirs assert(lfsr_mtree_weight(&lfs) == 3); @@ -3255,42 +3283,42 @@ code = ''' // setup our neighbors lfsr_openedmdir_t left_neighbor; - lfsr_mtree_lookup(&lfs, 0, &left_neighbor.mdir) => 0; - assert(left_neighbor.mdir.rbyd.weight == 1); - left_neighbor.rid = 0; + lfsr_mtree_lookup(&lfs, 0, -1, &left_neighbor.mdir) => 0; + assert(left_neighbor.mdir.m.rbyd.weight == 1); + left_neighbor.mdir.rid = 0; lfsr_openedmdir_t right_neighbor; - lfsr_mtree_lookup(&lfs, 2, &right_neighbor.mdir) => 0; - assert(right_neighbor.mdir.rbyd.weight == 1); - right_neighbor.rid = 0; + lfsr_mtree_lookup(&lfs, 2, -1, &right_neighbor.mdir) => 0; + assert(right_neighbor.mdir.m.rbyd.weight == 1); + right_neighbor.mdir.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, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[3 % 26], SIZE); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mdir to compact - mdir.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){-1}, NULL, 0) => 0; + mdir.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &mdir, NULL, 0) => 0; // we should now have 4 mdirs assert(lfsr_mtree_weight(&lfs) == 4); // assert that our neighbors were updated correctly - assert(left_neighbor.rid == 0); assert(left_neighbor.mdir.mid == 0); - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(memcmp(&left_neighbor.mdir, &mdir, sizeof(lfsr_mdir_t)) == 0); + assert(left_neighbor.mdir.rid == 0); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(memcmp(&left_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); - assert(right_neighbor.rid == 0); assert(right_neighbor.mdir.mid == 3); - lfsr_mtree_lookup(&lfs, 3, &mdir) => 0; - assert(memcmp(&right_neighbor.mdir, &mdir, sizeof(lfsr_mdir_t)) == 0); + assert(right_neighbor.mdir.rid == 0); + lfsr_mtree_lookup(&lfs, 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); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -3310,7 +3338,7 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; //// create a situation where we have 3 mdirs in our tree @@ -3318,30 +3346,30 @@ code = ''' // first force mroot to uninlined+split uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // we should now have 2 mdirs assert(lfsr_mtree_weight(&lfs) == 2); // now force one of our siblings to split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 1, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mdir to compact - mdir.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){-1}, NULL, 0) => 0; + mdir.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &mdir, NULL, 0) => 0; // we should now have 3 mdirs assert(lfsr_mtree_weight(&lfs) == 3); @@ -3351,37 +3379,37 @@ code = ''' // setup our neighbors lfsr_openedmdir_t left_neighbor; - lfsr_mtree_lookup(&lfs, 0, &left_neighbor.mdir) => 0; - assert(left_neighbor.mdir.rbyd.weight == 1); - left_neighbor.rid = 0; + lfsr_mtree_lookup(&lfs, 0, -1, &left_neighbor.mdir) => 0; + assert(left_neighbor.mdir.m.rbyd.weight == 1); + left_neighbor.mdir.rid = 0; lfsr_openedmdir_t right_neighbor; - lfsr_mtree_lookup(&lfs, 2, &right_neighbor.mdir) => 0; - assert(right_neighbor.mdir.rbyd.weight == 1); - right_neighbor.rid = 0; + lfsr_mtree_lookup(&lfs, 2, -1, &right_neighbor.mdir) => 0; + assert(right_neighbor.mdir.m.rbyd.weight == 1); + right_neighbor.mdir.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, &mdir) => 0; - assert(mdir.rbyd.weight == 1); - lfsr_mdir_commit(&lfs, &mdir, &(lfs_ssize_t){0}, LFSR_ATTRS( + lfsr_mtree_lookup(&lfs, 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; // we should now have 2 mdirs assert(lfsr_mtree_weight(&lfs) == 2); // assert that our neighbors were updated correctly - assert(left_neighbor.rid == 0); assert(left_neighbor.mdir.mid == 0); - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(memcmp(&left_neighbor.mdir, &mdir, sizeof(lfsr_mdir_t)) == 0); + assert(left_neighbor.mdir.rid == 0); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(memcmp(&left_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); - assert(right_neighbor.rid == 0); assert(right_neighbor.mdir.mid == 1); - lfsr_mtree_lookup(&lfs, 1, &mdir) => 0; - assert(memcmp(&right_neighbor.mdir, &mdir, sizeof(lfsr_mdir_t)) == 0); + assert(right_neighbor.mdir.rid == 0); + lfsr_mtree_lookup(&lfs, 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); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -3402,15 +3430,15 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // insert a new entry, this should update our neighbors - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, &alphas[0 % 26], 1))) => 0; // assert that our entry is still in the mtree - assert(lfs.mroot.rbyd.weight == 1); + assert(lfs.mroot.m.rbyd.weight == 1); uint8_t buffer[1]; lfsr_mdir_get(&lfs, &lfs.mroot, 0, LFSR_TAG_INLINED, @@ -3452,11 +3480,11 @@ code = ''' printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", mid_, tag_, - mdir->rbyd.block, mdir->redund_block); + mdir->m.rbyd.block, mdir->m.redund_block); // keep track of seen blocks - seen[mdir->rbyd.block / 8] |= 1 << (mdir->rbyd.block % 8); - seen[mdir->redund_block / 8] |= 1 << (mdir->redund_block % 8); + seen[mdir->m.rbyd.block / 8] |= 1 << (mdir->m.rbyd.block % 8); + seen[mdir->m.redund_block / 8] |= 1 << (mdir->m.redund_block % 8); } else { // this shouldn't happen printf("traversal: %d 0x%x %d\n", @@ -3481,7 +3509,7 @@ code = ''' // and the tree should still work // assert that our entry is still in the mtree - assert(lfs.mroot.rbyd.weight == 1); + assert(lfs.mroot.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &lfs.mroot, 0, LFSR_TAG_INLINED, buffer, 1) => 1; @@ -3502,28 +3530,28 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // prepare mroot with a large attr so the next entry can not fit uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // create a large entry that needs to be uninlined (but not split!) memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdir was unininlined correctly assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -3532,8 +3560,8 @@ code = ''' // assert that our entry is still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -3574,11 +3602,11 @@ code = ''' printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", mid_, tag_, - mdir->rbyd.block, mdir->redund_block); + mdir->m.rbyd.block, mdir->m.redund_block); // keep track of seen blocks - seen[mdir->rbyd.block / 8] |= 1 << (mdir->rbyd.block % 8); - seen[mdir->redund_block / 8] |= 1 << (mdir->redund_block % 8); + seen[mdir->m.rbyd.block / 8] |= 1 << (mdir->m.rbyd.block % 8); + seen[mdir->m.redund_block / 8] |= 1 << (mdir->m.redund_block % 8); } else { // this shouldn't happen printf("traversal: %d 0x%x %d\n", @@ -3605,7 +3633,7 @@ code = ''' // assert mdir was unininlined correctly assert(lfsr_mtree_weight(&lfs) == 1); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our attr is still in the mroot lfsr_mdir_get(&lfs, &lfs.mroot, -1, LFSR_TAG_UATTR(1), @@ -3613,8 +3641,8 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -3635,39 +3663,39 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create 2 large entries that needs to be uninlined and split uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, INLINED, +1, buffer, SIZE))) => 0; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(1, INLINED, +1, buffer, SIZE))) => 0; // force mroot to compact - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdirs were unininlined and split assert(lfsr_mtree_weight(&lfs) == 2); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our entries are still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 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, &msibling) => 0; - assert(msibling.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -1, &msibling) => 0; + assert(msibling.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &msibling, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[1 % 26], 1) == 0); @@ -3707,11 +3735,11 @@ code = ''' printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", mid_, tag_, - mdir->rbyd.block, mdir->redund_block); + mdir->m.rbyd.block, mdir->m.redund_block); // keep track of seen blocks - seen[mdir->rbyd.block / 8] |= 1 << (mdir->rbyd.block % 8); - seen[mdir->redund_block / 8] |= 1 << (mdir->redund_block % 8); + seen[mdir->m.rbyd.block / 8] |= 1 << (mdir->m.rbyd.block % 8); + seen[mdir->m.redund_block / 8] |= 1 << (mdir->m.redund_block % 8); } else { // this shouldn't happen printf("traversal: %d 0x%x %d\n", @@ -3738,17 +3766,17 @@ code = ''' // assert mdirs were unininlined and split assert(lfsr_mtree_weight(&lfs) == 2); // assert mroot now has no entries - assert(lfs.mroot.rbyd.weight == 0); + assert(lfs.mroot.m.rbyd.weight == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, &mdir) => 0; - assert(mdir.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 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, &msibling) => 0; - assert(msibling.rbyd.weight == 1); + lfsr_mtree_lookup(&lfs, 1, -1, &msibling) => 0; + assert(msibling.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &msibling, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[1 % 26], 1) == 0); @@ -3770,23 +3798,23 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // prepare mroot with an attr uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // force mroot to compact twice, this should extend the mroot lfsr_mdir_t old_mroot = lfs.mroot; - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; - lfs.mroot.rbyd.off = BLOCK_SIZE; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // assert we relocated @@ -3832,11 +3860,11 @@ code = ''' printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", mid_, tag_, - mdir->rbyd.block, mdir->redund_block); + mdir->m.rbyd.block, mdir->m.redund_block); // keep track of seen blocks - seen[mdir->rbyd.block / 8] |= 1 << (mdir->rbyd.block % 8); - seen[mdir->redund_block / 8] |= 1 << (mdir->redund_block % 8); + seen[mdir->m.rbyd.block / 8] |= 1 << (mdir->m.rbyd.block % 8); + seen[mdir->m.redund_block / 8] |= 1 << (mdir->m.redund_block % 8); } else { // this shouldn't happen printf("traversal: %d 0x%x %d\n", @@ -3884,30 +3912,30 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // create entries lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, -1, &mdir) => 0; - lfs_ssize_t rid = 0; + mdir.rid = 0; for (lfs_size_t i = 0; i < N; i++) { // force a compaction? if (FORCE_COMPACTION) { - mdir.rbyd.off = cfg->block_size; - lfs.mroot.rbyd.off = cfg->block_size; + mdir.m.rbyd.off = cfg->block_size; + lfs.mroot.m.rbyd.off = cfg->block_size; } - lfsr_mdir_commit(&lfs, &mdir, &rid, LFSR_ATTRS( - LFSR_ATTR(rid, INLINED, +1, &alphas[i % 26], 1))) => 0; + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( + LFSR_ATTR(mdir.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); - rid += 1; + mdir.rid += 1; } // try looking up each entry @@ -3916,12 +3944,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, &mdir) => 0; - for (lfs_ssize_t rid = 0; - rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); - rid++) { + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + for (mdir.rid = 0; + mdir.rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); + mdir.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -3964,11 +3992,11 @@ code = ''' printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", mid_, tag_, - mdir->rbyd.block, mdir->redund_block); + mdir->m.rbyd.block, mdir->m.redund_block); // keep track of seen blocks - seen[mdir->rbyd.block / 8] |= 1 << (mdir->rbyd.block % 8); - seen[mdir->redund_block / 8] |= 1 << (mdir->redund_block % 8); + seen[mdir->m.rbyd.block / 8] |= 1 << (mdir->m.rbyd.block % 8); + seen[mdir->m.redund_block / 8] |= 1 << (mdir->m.redund_block % 8); } else { // this shouldn't happen printf("traversal: %d 0x%x %d\n", @@ -3998,12 +4026,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, &mdir) => 0; - for (lfs_ssize_t rid = 0; - rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); - rid++) { + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + for (mdir.rid = 0; + mdir.rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); + mdir.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -4028,7 +4056,7 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; // at least keep track of the number of entries we expect @@ -4042,23 +4070,23 @@ code = ''' : (lfs_ssize_t)(TEST_PRNG(&prng) % lfsr_mtree_weight(&lfs)); // fetch mdir lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, &mdir) => 0; + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; // choose a pseudo-random rid - lfs_ssize_t rid = TEST_PRNG(&prng) % (lfsr_mdir_weight(&mdir)+1); + mdir.rid = TEST_PRNG(&prng) % (lfsr_mdir_weight(&mdir)+1); // force a compaction? if (FORCE_COMPACTION) { - mdir.rbyd.off = cfg->block_size; - lfs.mroot.rbyd.off = cfg->block_size; + mdir.m.rbyd.off = cfg->block_size; + lfs.mroot.m.rbyd.off = cfg->block_size; } // add to rbyd, potentially splitting the mdir - lfsr_mdir_commit(&lfs, &mdir, &rid, LFSR_ATTRS( - LFSR_ATTR(rid, INLINED, +1, &alphas[i % 26], 1))) => 0; + lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( + LFSR_ATTR(mdir.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, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); @@ -4072,12 +4100,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, &mdir) => 0; - for (lfs_ssize_t rid = 0; - rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); - rid++) { + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + for (mdir.rid = 0; + mdir.rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); + mdir.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -4124,11 +4152,11 @@ code = ''' printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", mid_, tag_, - mdir->rbyd.block, mdir->redund_block); + mdir->m.rbyd.block, mdir->m.redund_block); // keep track of seen blocks - seen[mdir->rbyd.block / 8] |= 1 << (mdir->rbyd.block % 8); - seen[mdir->redund_block / 8] |= 1 << (mdir->redund_block % 8); + seen[mdir->m.rbyd.block / 8] |= 1 << (mdir->m.rbyd.block % 8); + seen[mdir->m.redund_block / 8] |= 1 << (mdir->m.redund_block % 8); } else { // this shouldn't happen printf("traversal: %d 0x%x %d\n", @@ -4159,12 +4187,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, &mdir) => 0; - for (lfs_ssize_t rid = 0; - rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); - rid++) { + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + for (mdir.rid = 0; + mdir.rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); + mdir.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -4193,7 +4221,7 @@ code = ''' uint8_t buffer[LFSR_MPTR_DSIZE]; lfs_ssize_t d = lfsr_mptr_todisk(&lfs, LFSR_MPTR_MROOTANCHOR, buffer); assert(d >= 0); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, MROOT, 0, buffer, d))) => 0; // technically, cycle detection only needs to work when we're validating @@ -4225,7 +4253,7 @@ code = ''' printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", mid_, tag_, - mdir->rbyd.block, mdir->redund_block); + mdir->m.rbyd.block, mdir->m.redund_block); } else { // this shouldn't happen printf("traversal: %d 0x%x %d\n", @@ -4278,17 +4306,17 @@ code = ''' // prepare mroot with an attr uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // force mroot to compact twice, this should extend the mroot lfsr_mdir_t old_mroot = lfs.mroot; - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; - lfs.mroot.rbyd.off = BLOCK_SIZE; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // assert we relocated @@ -4333,19 +4361,19 @@ code = ''' // prepare mroot with an attr uint8_t buffer[SIZE]; memset(buffer, alphas[0 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // force mroot to compact 2x2 times, this should extend the mroot twice lfsr_mdir_t old_mroot = lfs.mroot; for (int i = 0; i < 4; i++) { - lfs.mroot.rbyd.off = BLOCK_SIZE; - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, NULL, 0) => 0; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; + lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; } - lfs.mroot.rbyd.off = BLOCK_SIZE; + lfs.mroot.m.rbyd.off = BLOCK_SIZE; memset(buffer, alphas[1 % 26], SIZE); - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(-1, UATTR(1), 0, buffer, SIZE))) => 0; // assert we relocated diff --git a/tests/t4_alloc.toml b/tests/t4_alloc.toml index 4eaf0846..0f32a2ab 100644 --- a/tests/t4_alloc.toml +++ b/tests/t4_alloc.toml @@ -104,12 +104,12 @@ code = ''' lfsr_mount(&lfs, cfg) => 0; lfs_alloc_ack(&lfs); // remove root dstart for now - lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS( + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, &mdir) => 0; - lfs_ssize_t rid = 0; + lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, -1, &mdir) => 0; + mdir.rid = 0; lfs_size_t count = 0; while (true) { @@ -120,20 +120,20 @@ code = ''' lfs_alloc_ack(&lfs); // keep creating new metadata entries until we run out of space - int err = lfsr_mdir_commit(&lfs, &mdir, &rid, LFSR_ATTRS( - LFSR_ATTR(rid, INLINED, +1, &alphas[count % 26], 1))); + int err = lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( + LFSR_ATTR(mdir.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, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[count % 26], 1) == 0); count += 1; - rid += 1; + mdir.rid += 1; } printf("alloced %d metadata entries in %d blocks\n", @@ -145,12 +145,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, &mdir) => 0; - for (lfs_ssize_t rid = 0; - rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); - rid++) { + lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + for (mdir.rid = 0; + mdir.rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir); + mdir.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1;