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;