t: Dropped mtinfo/btinfo, just use data/bptr for everything
It's probably a bad reason, but this avoids wasting too much time
figuring out how to name things.
Now most traversal functions return an lfsr_tag_t + lfsr_bptr_t pair,
which is enough to describe the current relevant traversal objects:
tag=LFSR_TAG_MDIR => (lfsr_mdir_t*)bptr.data.u.buffer
tag=LFSR_TAG_BRANCH => (lfsr_rbyd_t*)bptr.data.u.buffer
tag=LFSR_TAG_DATA => bptr.data
tag=LFSR_TAG_BPTR => bptr
This would be a bit better if lfsr_data_t's buffer field was a void*,
but that would mess with byte-level arithmetic, which is more common
with lfsr_data_ts.
This also adopts the fragmented/optional out-params used elsewhere in
the codebase. I thought this would add quite a bit more stack cost,
since we need redundant tags/bptrs to make lfsr_mtree_traverse/
lfsr_mtree_gc work, but surprisingly not:
code stack
before: 35256 2680
after: 35228 (-0.1%) 2680 (+0.0%)
It seems we make up the extra stack cost of redundant tags/bptrs by
giving the compiler more stack-alloc flexibility, tighter per-function
return types, and opting-out of tags/bptrs in most low-level traversals:
lfs_alloc mainly.
But if the fragmented/optional out-params is net harmful for code/stack
size, we should reconsider the pattern system-wide. This does probably
deserve a second look in the future...
This commit is contained in:
@@ -4987,21 +4987,9 @@ static lfs_scmp_t lfsr_btree_namelookup(lfs_t *lfs, const lfsr_btree_t *btree,
|
||||
.branch=NULL, \
|
||||
.rid=0})
|
||||
|
||||
typedef struct lfsr_btinfo {
|
||||
lfsr_tag_t tag;
|
||||
union {
|
||||
// ignore the mdir here, things get a bit simpler if we can
|
||||
// alias mtinfo=btinfo
|
||||
lfsr_mdir_t *mdir;
|
||||
lfsr_rbyd_t *rbyd;
|
||||
lfsr_data_t data;
|
||||
lfsr_bptr_t bptr;
|
||||
} u;
|
||||
} lfsr_btinfo_t;
|
||||
|
||||
static int lfsr_btree_traverse_(lfs_t *lfs, lfsr_btree_t *btree,
|
||||
static int lfsr_btree_traverse(lfs_t *lfs, const lfsr_btree_t *btree,
|
||||
lfsr_btraversal_t *bt,
|
||||
lfsr_bid_t *bid_, lfsr_btinfo_t *btinfo) {
|
||||
lfsr_bid_t *bid_, lfsr_tag_t *tag_, lfsr_data_t *data_) {
|
||||
// explicitly traverse the root even if weight=0
|
||||
if (!bt->branch) {
|
||||
bt->branch = btree;
|
||||
@@ -5016,8 +5004,12 @@ static int lfsr_btree_traverse_(lfs_t *lfs, lfsr_btree_t *btree,
|
||||
if (bid_) {
|
||||
*bid_ = btree->weight-1;
|
||||
}
|
||||
btinfo->tag = LFSR_TAG_BRANCH;
|
||||
btinfo->u.rbyd = bt->branch;
|
||||
if (tag_) {
|
||||
*tag_ = LFSR_TAG_BRANCH;
|
||||
}
|
||||
if (data_) {
|
||||
data_->u.buffer = (const uint8_t*)bt->branch;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -5069,8 +5061,12 @@ static int lfsr_btree_traverse_(lfs_t *lfs, lfsr_btree_t *btree,
|
||||
if (bid_) {
|
||||
*bid_ = bt->bid + (rid__ - bt->rid);
|
||||
}
|
||||
btinfo->tag = LFSR_TAG_BRANCH;
|
||||
btinfo->u.rbyd = bt->branch;
|
||||
if (tag_) {
|
||||
*tag_ = LFSR_TAG_BRANCH;
|
||||
}
|
||||
if (data_) {
|
||||
data_->u.buffer = (const uint8_t*)bt->branch;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5087,19 +5083,17 @@ static int lfsr_btree_traverse_(lfs_t *lfs, lfsr_btree_t *btree,
|
||||
if (bid_) {
|
||||
*bid_ = bid__;
|
||||
}
|
||||
btinfo->tag = tag__;
|
||||
btinfo->u.data = data__;
|
||||
if (tag_) {
|
||||
*tag_ = tag__;
|
||||
}
|
||||
if (data_) {
|
||||
*data_ = data__;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int lfsr_btree_traverse(lfs_t *lfs, lfsr_btree_t *btree,
|
||||
lfsr_btraversal_t *bt,
|
||||
lfsr_bid_t *bid_, lfsr_btinfo_t *btinfo) {
|
||||
return lfsr_btree_traverse_(lfs, btree, bt, bid_, btinfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// B-shrub operations ///
|
||||
@@ -5588,9 +5582,9 @@ static int lfsr_bshrub_lookupnext(lfs_t *lfs,
|
||||
}
|
||||
|
||||
static int lfsr_bshrub_traverse(lfs_t *lfs,
|
||||
const lfsr_mdir_t *mdir, lfsr_bshrub_t *bshrub,
|
||||
const lfsr_mdir_t *mdir, const lfsr_bshrub_t *bshrub,
|
||||
lfsr_btraversal_t *bt,
|
||||
lfsr_bid_t *bid_, lfsr_btinfo_t *btinfo) {
|
||||
lfsr_bid_t *bid_, lfsr_tag_t *tag_, lfsr_bptr_t *bptr_) {
|
||||
// bnull/bsprout do nothing
|
||||
if (lfsr_bshrub_isbnull(bshrub)
|
||||
|| lfsr_bshrub_isbsprout(mdir, bshrub)) {
|
||||
@@ -5606,27 +5600,38 @@ static int lfsr_bshrub_traverse(lfs_t *lfs,
|
||||
if (bid_) {
|
||||
*bid_ = lfsr_data_size(bshrub->u.bptr.data)-1;
|
||||
}
|
||||
btinfo->tag = LFSR_TAG_BLOCK;
|
||||
btinfo->u.bptr = bshrub->u.bptr;
|
||||
if (tag_) {
|
||||
*tag_ = LFSR_TAG_BLOCK;
|
||||
}
|
||||
if (bptr_) {
|
||||
*bptr_ = bshrub->u.bptr;
|
||||
}
|
||||
return 0;
|
||||
|
||||
// bshrub/btree?
|
||||
} else if (lfsr_bshrub_isbshruborbtree(bshrub)) {
|
||||
int err = lfsr_btree_traverse_(lfs, &bshrub->u.btree, bt,
|
||||
bid_, btinfo);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_data_t data;
|
||||
int err = lfsr_btree_traverse(lfs, &bshrub->u.btree, bt,
|
||||
bid_, &tag, &data);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// decode bptrs
|
||||
if (btinfo->tag == LFSR_TAG_BLOCK) {
|
||||
lfsr_bptr_t bptr;
|
||||
err = lfsr_data_readbptr(lfs, &btinfo->u.data,
|
||||
&bptr);
|
||||
if (err) {
|
||||
return err;
|
||||
if (tag_) {
|
||||
*tag_ = tag;
|
||||
}
|
||||
if (bptr_) {
|
||||
if (tag == LFSR_TAG_BLOCK) {
|
||||
err = lfsr_data_readbptr(lfs, &data,
|
||||
bptr_);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
bptr_->data = data;
|
||||
}
|
||||
btinfo->u.bptr = bptr;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -8266,15 +8271,12 @@ static inline bool lfsr_f_isdirty(uint32_t flags) {
|
||||
|
||||
|
||||
|
||||
// alias mtinfo=btinfo
|
||||
typedef lfsr_btinfo_t lfsr_mtinfo_t;
|
||||
|
||||
// needed in lfsr_mtree_traverse_
|
||||
static inline bool lfsr_f_isunsync(uint32_t flags);
|
||||
|
||||
// low-level traversal _only_ finds blocks
|
||||
static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_mtraversal_t *mt,
|
||||
lfsr_mtinfo_t *mtinfo) {
|
||||
lfsr_tag_t *tag_, lfsr_bptr_t *bptr_) {
|
||||
while (true) {
|
||||
switch (mt->o.o.state) {
|
||||
// start with the mrootanchor 0x{0,1}
|
||||
@@ -8292,8 +8294,12 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_mtraversal_t *mt,
|
||||
// transition to traversing the mroot chain
|
||||
mt->o.o.state = LFSR_MTSTATE_MROOTCHAIN;
|
||||
|
||||
mtinfo->tag = LFSR_TAG_MDIR;
|
||||
mtinfo->u.mdir = &mt->o.o.mdir;
|
||||
if (tag_) {
|
||||
*tag_ = LFSR_TAG_MDIR;
|
||||
}
|
||||
if (bptr_) {
|
||||
bptr_->data.u.buffer = (const uint8_t*)&mt->o.o.mdir;
|
||||
}
|
||||
return 0;
|
||||
|
||||
// traverse the mroot chain, checking for mroot/mtree/mdir
|
||||
@@ -8348,8 +8354,12 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_mtraversal_t *mt,
|
||||
return err;
|
||||
}
|
||||
|
||||
mtinfo->tag = LFSR_TAG_MDIR;
|
||||
mtinfo->u.mdir = &mt->o.o.mdir;
|
||||
if (tag_) {
|
||||
*tag_ = LFSR_TAG_MDIR;
|
||||
}
|
||||
if (bptr_) {
|
||||
bptr_->data.u.buffer = (const uint8_t*)&mt->o.o.mdir;
|
||||
}
|
||||
return 0;
|
||||
|
||||
// found an mdir?
|
||||
@@ -8369,8 +8379,12 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_mtraversal_t *mt,
|
||||
// transition to traversing the mdir
|
||||
mt->o.o.state = LFSR_MTSTATE_MDIR;
|
||||
|
||||
mtinfo->tag = LFSR_TAG_MDIR;
|
||||
mtinfo->u.mdir = &mt->o.o.mdir;
|
||||
if (tag_) {
|
||||
*tag_ = LFSR_TAG_MDIR;
|
||||
}
|
||||
if (bptr_) {
|
||||
bptr_->data.u.buffer = (const uint8_t*)&mt->o.o.mdir;
|
||||
}
|
||||
return 0;
|
||||
|
||||
// found an mtree?
|
||||
@@ -8408,8 +8422,12 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_mtraversal_t *mt,
|
||||
// transition to traversing the mdir
|
||||
mt->o.o.state = LFSR_MTSTATE_MDIR;
|
||||
|
||||
mtinfo->tag = LFSR_TAG_MDIR;
|
||||
mtinfo->u.mdir = &mt->o.o.mdir;
|
||||
if (tag_) {
|
||||
*tag_ = LFSR_TAG_MDIR;
|
||||
}
|
||||
if (bptr_) {
|
||||
bptr_->data.u.buffer = (const uint8_t*)&mt->o.o.mdir;
|
||||
}
|
||||
return 0;
|
||||
|
||||
// scan for blocks/btrees in the current mdir
|
||||
@@ -8505,7 +8523,7 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_mtraversal_t *mt,
|
||||
// traverse through our file
|
||||
err = lfsr_bshrub_traverse(lfs, &mt->o.o.mdir, &mt->o.bshrub,
|
||||
&mt->u.bt,
|
||||
NULL, mtinfo);
|
||||
NULL, &tag, bptr_);
|
||||
if (err) {
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
// end of mtree? start iterating over mdirs
|
||||
@@ -8531,11 +8549,17 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_mtraversal_t *mt,
|
||||
}
|
||||
|
||||
// found an inner btree node?
|
||||
if (mtinfo->tag == LFSR_TAG_BRANCH) {
|
||||
if (tag == LFSR_TAG_BRANCH) {
|
||||
if (tag_) {
|
||||
*tag_ = tag;
|
||||
}
|
||||
return 0;
|
||||
|
||||
// found an indirect block?
|
||||
} else if (mtinfo->tag == LFSR_TAG_BLOCK) {
|
||||
} else if (tag == LFSR_TAG_BLOCK) {
|
||||
if (tag_) {
|
||||
*tag_ = tag;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -8557,8 +8581,11 @@ static void lfs_alloc_markinuse(lfs_t *lfs, lfs_block_t block);
|
||||
// but no mutation! (we're called in lfs_alloc, so things would end up
|
||||
// recursive)
|
||||
static int lfsr_mtree_traverse(lfs_t *lfs, lfsr_mtraversal_t *mt,
|
||||
lfsr_mtinfo_t *mtinfo) {
|
||||
int err = lfsr_mtree_traverse_(lfs, mt, mtinfo);
|
||||
lfsr_tag_t *tag_, lfsr_bptr_t *bptr_) {
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
int err = lfsr_mtree_traverse_(lfs, mt,
|
||||
&tag, &bptr);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -8568,10 +8595,11 @@ static int lfsr_mtree_traverse(lfs_t *lfs, lfsr_mtraversal_t *mt,
|
||||
|| lfsr_t_isck(mt->o.o.flags)
|
||||
// we also need to fetch to know if we need to compact
|
||||
|| lfsr_t_iscompact(mt->o.o.flags))
|
||||
&& mtinfo->tag == LFSR_TAG_BRANCH) {
|
||||
err = lfsr_rbyd_fetchck(lfs, mtinfo->u.rbyd,
|
||||
mtinfo->u.rbyd->blocks[0], mtinfo->u.rbyd->trunk,
|
||||
mtinfo->u.rbyd->cksum);
|
||||
&& tag == LFSR_TAG_BRANCH) {
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
||||
err = lfsr_rbyd_fetchck(lfs, rbyd,
|
||||
rbyd->blocks[0], rbyd->trunk,
|
||||
rbyd->cksum);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -8579,8 +8607,8 @@ static int lfsr_mtree_traverse(lfs_t *lfs, lfsr_mtraversal_t *mt,
|
||||
|
||||
// validate data blocks?
|
||||
if (lfsr_t_isck(mt->o.o.flags)
|
||||
&& mtinfo->tag == LFSR_TAG_BLOCK) {
|
||||
err = lfsr_bptr_ck(lfs, &mtinfo->u.bptr);
|
||||
&& tag == LFSR_TAG_BLOCK) {
|
||||
err = lfsr_bptr_ck(lfs, &bptr);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -8588,57 +8616,69 @@ static int lfsr_mtree_traverse(lfs_t *lfs, lfsr_mtraversal_t *mt,
|
||||
|
||||
// track in-use blocks
|
||||
if (lfsr_t_islookahead(mt->o.o.flags)) {
|
||||
if (mtinfo->tag == LFSR_TAG_MDIR) {
|
||||
lfs_alloc_markinuse(lfs, mtinfo->u.mdir->rbyd.blocks[0]);
|
||||
lfs_alloc_markinuse(lfs, mtinfo->u.mdir->rbyd.blocks[1]);
|
||||
if (tag == LFSR_TAG_MDIR) {
|
||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
||||
lfs_alloc_markinuse(lfs, mdir->rbyd.blocks[0]);
|
||||
lfs_alloc_markinuse(lfs, mdir->rbyd.blocks[1]);
|
||||
|
||||
} else if (mtinfo->tag == LFSR_TAG_BRANCH) {
|
||||
lfs_alloc_markinuse(lfs, mtinfo->u.rbyd->blocks[0]);
|
||||
} else if (tag == LFSR_TAG_BRANCH) {
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
||||
lfs_alloc_markinuse(lfs, rbyd->blocks[0]);
|
||||
|
||||
} else if (mtinfo->tag == LFSR_TAG_BLOCK) {
|
||||
lfs_alloc_markinuse(lfs, mtinfo->u.bptr.data.u.disk.block);
|
||||
} else if (tag == LFSR_TAG_BLOCK) {
|
||||
lfs_alloc_markinuse(lfs, bptr.data.u.disk.block);
|
||||
|
||||
} else {
|
||||
LFS_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
if (tag_) {
|
||||
*tag_ = tag;
|
||||
}
|
||||
if (bptr_) {
|
||||
*bptr_ = bptr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// high-level mutating traversal, handle extra features that require
|
||||
// mutation here, upper layers should call lfs_alloc_ckpoint as needed
|
||||
static int lfsr_mtree_gc(lfs_t *lfs, lfsr_mtraversal_t *mt,
|
||||
lfsr_mtinfo_t *mtinfo) {
|
||||
lfsr_tag_t *tag_, lfsr_bptr_t *bptr_) {
|
||||
// traversals need to be enrolled in our opened list for
|
||||
// lfsr_mtree_gc to work correctly
|
||||
LFS_ASSERT(lfsr_omdir_isopen(lfs, &mt->o.o));
|
||||
|
||||
int err = lfsr_mtree_traverse(lfs, mt, mtinfo);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
int err = lfsr_mtree_traverse(lfs, mt,
|
||||
&tag, &bptr);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// compacting mdirs?
|
||||
if (lfsr_t_iscompact(mt->o.o.flags)
|
||||
&& mtinfo->tag == LFSR_TAG_MDIR
|
||||
&& tag == LFSR_TAG_MDIR
|
||||
// exceed compaction threshold?
|
||||
&& lfsr_rbyd_eoff(&mtinfo->u.mdir->rbyd)
|
||||
&& lfsr_rbyd_eoff(&((lfsr_mdir_t*)bptr.data.u.buffer)->rbyd)
|
||||
> ((lfs->cfg->gc_compact_thresh)
|
||||
? lfs->cfg->gc_compact_thresh
|
||||
: lfs->cfg->block_size - lfs->cfg->block_size/8)) {
|
||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
||||
LFS_DEBUG("Compacting mdir %"PRId32" "
|
||||
"0x{%"PRIx32",%"PRIx32"} "
|
||||
"(%"PRId32" > %"PRId32")",
|
||||
mtinfo->u.mdir->mid >> lfs->mdir_bits,
|
||||
mtinfo->u.mdir->rbyd.blocks[0],
|
||||
mtinfo->u.mdir->rbyd.blocks[1],
|
||||
lfsr_rbyd_eoff(&mtinfo->u.mdir->rbyd),
|
||||
mdir->mid >> lfs->mdir_bits,
|
||||
mdir->rbyd.blocks[0],
|
||||
mdir->rbyd.blocks[1],
|
||||
lfsr_rbyd_eoff(&mdir->rbyd),
|
||||
(lfs->cfg->gc_compact_thresh)
|
||||
? lfs->cfg->gc_compact_thresh
|
||||
: lfs->cfg->block_size - lfs->cfg->block_size/8);
|
||||
|
||||
int err = lfsr_mdir_compact(lfs, mtinfo->u.mdir);
|
||||
int err = lfsr_mdir_compact(lfs, mdir);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -8649,17 +8689,18 @@ static int lfsr_mtree_gc(lfs_t *lfs, lfsr_mtraversal_t *mt,
|
||||
|
||||
// compacting btree nodes?
|
||||
if (lfsr_t_iscompact(mt->o.o.flags)
|
||||
&& mtinfo->tag == LFSR_TAG_BRANCH
|
||||
&& tag == LFSR_TAG_BRANCH
|
||||
// exceed compaction threshold?
|
||||
&& lfsr_rbyd_eoff(mtinfo->u.rbyd)
|
||||
&& lfsr_rbyd_eoff((lfsr_rbyd_t*)bptr.data.u.buffer)
|
||||
> ((lfs->cfg->gc_compact_thresh)
|
||||
? lfs->cfg->gc_compact_thresh
|
||||
: lfs->cfg->block_size - lfs->cfg->block_size/8)) {
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
||||
LFS_DEBUG("Compacting rbyd 0x%"PRIx32".%"PRIx32" "
|
||||
"(%"PRId32" > %"PRId32")",
|
||||
mtinfo->u.rbyd->blocks[0],
|
||||
lfsr_rbyd_trunk(mtinfo->u.rbyd),
|
||||
lfsr_rbyd_eoff(mtinfo->u.rbyd),
|
||||
rbyd->blocks[0],
|
||||
lfsr_rbyd_trunk(rbyd),
|
||||
lfsr_rbyd_eoff(rbyd),
|
||||
(lfs->cfg->gc_compact_thresh)
|
||||
? lfs->cfg->gc_compact_thresh
|
||||
: lfs->cfg->block_size - lfs->cfg->block_size/8);
|
||||
@@ -8667,14 +8708,14 @@ static int lfsr_mtree_gc(lfs_t *lfs, lfsr_mtraversal_t *mt,
|
||||
if (mt->o.o.state == LFSR_MTSTATE_MTREE) {
|
||||
int err = lfsr_btree_compact_(lfs, &mt->o.bshrub.u.btree,
|
||||
// note we may be referencing the btree root here
|
||||
mt->u.bt.bid, mtinfo->u.rbyd);
|
||||
mt->u.bt.bid, rbyd);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
int err = lfsr_bshrub_compact_(lfs, &mt->o.o.mdir, &mt->o.bshrub,
|
||||
// note we may be referencing the btree root here
|
||||
mt->u.bt.bid, mtinfo->u.rbyd);
|
||||
mt->u.bt.bid, rbyd);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -8724,6 +8765,12 @@ static int lfsr_mtree_gc(lfs_t *lfs, lfsr_mtraversal_t *mt,
|
||||
mt->o.o.flags |= LFS_F_DIRTY;
|
||||
}
|
||||
|
||||
if (tag_) {
|
||||
*tag_ = tag;
|
||||
}
|
||||
if (bptr_) {
|
||||
*bptr_ = bptr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -8865,8 +8912,8 @@ static lfs_sblock_t lfs_alloc(lfs_t *lfs, bool erase) {
|
||||
// in use in our lookahead window
|
||||
lfsr_mtraversal_t mt = LFSR_MTRAVERSAL(LFS_T_LOOKAHEAD);
|
||||
while (true) {
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
int err = lfsr_mtree_traverse(lfs, &mt, &mtinfo);
|
||||
int err = lfsr_mtree_traverse(lfs, &mt,
|
||||
NULL, NULL);
|
||||
if (err) {
|
||||
LFS_ASSERT(err != LFS_ERR_BUSY);
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
@@ -12251,8 +12298,10 @@ static int lfsr_mountinited(lfs_t *lfs) {
|
||||
lfsr_mtraversal_t mt = LFSR_MTRAVERSAL(
|
||||
LFS_T_MTREEONLY | LFS_T_CKMETA);
|
||||
while (true) {
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
int err = lfsr_mtree_traverse(lfs, &mt, &mtinfo);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
int err = lfsr_mtree_traverse(lfs, &mt,
|
||||
&tag, &bptr);
|
||||
if (err) {
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
@@ -12261,13 +12310,13 @@ static int lfsr_mountinited(lfs_t *lfs) {
|
||||
}
|
||||
|
||||
// found an mdir?
|
||||
if (mtinfo.tag == LFSR_TAG_MDIR) {
|
||||
if (tag == LFSR_TAG_MDIR) {
|
||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
||||
// found an mroot?
|
||||
if (mtinfo.u.mdir->mid == -1) {
|
||||
if (mdir->mid == -1) {
|
||||
// check for the magic string, all mroot should have this
|
||||
lfsr_data_t data;
|
||||
int err = lfsr_mdir_lookup(lfs,
|
||||
mtinfo.u.mdir, LFSR_TAG_MAGIC,
|
||||
int err = lfsr_mdir_lookup(lfs, mdir, LFSR_TAG_MAGIC,
|
||||
&data);
|
||||
if (err) {
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
@@ -12288,14 +12337,14 @@ static int lfsr_mountinited(lfs_t *lfs) {
|
||||
}
|
||||
|
||||
// are we the last mroot?
|
||||
err = lfsr_mdir_lookup(lfs, mtinfo.u.mdir, LFSR_TAG_MROOT,
|
||||
err = lfsr_mdir_lookup(lfs, mdir, LFSR_TAG_MROOT,
|
||||
NULL);
|
||||
if (err && err != LFS_ERR_NOENT) {
|
||||
return err;
|
||||
}
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
// track active mroot
|
||||
lfs->mroot = *mtinfo.u.mdir;
|
||||
lfs->mroot = *mdir;
|
||||
|
||||
// mount/validate config in active mroot
|
||||
err = lfsr_mountmroot(lfs, &lfs->mroot);
|
||||
@@ -12308,28 +12357,27 @@ static int lfsr_mountinited(lfs_t *lfs) {
|
||||
// found a direct mdir? keep track of this
|
||||
if (lfsr_mtree_isnull(&lfs->mtree)) {
|
||||
lfs->mtree = LFSR_MTREE_MPTR(
|
||||
*lfsr_mdir_mptr(mtinfo.u.mdir),
|
||||
*lfsr_mdir_mptr(mdir),
|
||||
(1 << lfs->mdir_bits));
|
||||
}
|
||||
}
|
||||
|
||||
// toss our cksum into the filesystem seed for pseudorandom
|
||||
// numbers
|
||||
lfs->seed ^= mtinfo.u.mdir->rbyd.cksum;
|
||||
lfs->seed ^= mdir->rbyd.cksum;
|
||||
|
||||
// collect any gdeltas from this mdir
|
||||
err = lfsr_fs_consumegdelta(lfs, mtinfo.u.mdir);
|
||||
err = lfsr_fs_consumegdelta(lfs, mdir);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// check for any orphaned files
|
||||
for (lfs_size_t rid = 0;
|
||||
rid < mtinfo.u.mdir->rbyd.weight;
|
||||
rid < mdir->rbyd.weight;
|
||||
rid++) {
|
||||
lfsr_tag_t tag;
|
||||
err = lfsr_rbyd_sublookup(lfs, &mtinfo.u.mdir->rbyd,
|
||||
rid, LFSR_TAG_NAME,
|
||||
err = lfsr_rbyd_sublookup(lfs, &mdir->rbyd, rid, LFSR_TAG_NAME,
|
||||
&tag, NULL);
|
||||
if (err) {
|
||||
LFS_ASSERT(err != LFS_ERR_NOENT);
|
||||
@@ -12342,8 +12390,7 @@ static int lfsr_mountinited(lfs_t *lfs) {
|
||||
if (tag == LFSR_TAG_ORPHAN) {
|
||||
LFS_DEBUG("Found orphaned file "
|
||||
"%"PRId32".%"PRId32,
|
||||
lfsr_mid_bid(lfs, mtinfo.u.mdir->mid)
|
||||
>> lfs->mdir_bits,
|
||||
lfsr_mid_bid(lfs, mdir->mid) >> lfs->mdir_bits,
|
||||
rid);
|
||||
lfs->hasorphans = true;
|
||||
|
||||
@@ -12352,8 +12399,7 @@ static int lfsr_mountinited(lfs_t *lfs) {
|
||||
// TODO switch to readonly?
|
||||
LFS_ERROR("Found unknown file type "
|
||||
"%"PRId32".%"PRId32" 0x%"PRIx16,
|
||||
lfsr_mid_bid(lfs, mtinfo.u.mdir->mid)
|
||||
>> lfs->mdir_bits,
|
||||
lfsr_mid_bid(lfs, mdir->mid) >> lfs->mdir_bits,
|
||||
rid,
|
||||
lfsr_tag_subtype(tag));
|
||||
return LFS_ERR_NOTSUP;
|
||||
@@ -12361,10 +12407,11 @@ static int lfsr_mountinited(lfs_t *lfs) {
|
||||
}
|
||||
|
||||
// found an mtree inner-node?
|
||||
} else if (mtinfo.tag == LFSR_TAG_BRANCH) {
|
||||
} else if (tag == LFSR_TAG_BRANCH) {
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
||||
// found the root of the mtree? keep track of this
|
||||
if (lfsr_mtree_isnull(&lfs->mtree)) {
|
||||
lfs->mtree.u.btree = *mtinfo.u.rbyd;
|
||||
lfs->mtree.u.btree = *rbyd;
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -12562,8 +12609,9 @@ lfs_ssize_t lfsr_fs_size(lfs_t *lfs) {
|
||||
lfs_size_t count = 0;
|
||||
lfsr_mtraversal_t mt = LFSR_MTRAVERSAL(0);
|
||||
while (true) {
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
int err = lfsr_mtree_traverse(lfs, &mt, &mtinfo);
|
||||
lfsr_tag_t tag;
|
||||
int err = lfsr_mtree_traverse(lfs, &mt,
|
||||
&tag, NULL);
|
||||
if (err) {
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
@@ -12572,13 +12620,13 @@ lfs_ssize_t lfsr_fs_size(lfs_t *lfs) {
|
||||
}
|
||||
|
||||
// count the number of blocks we see, yes this may result in duplicates
|
||||
if (mtinfo.tag == LFSR_TAG_MDIR) {
|
||||
if (tag == LFSR_TAG_MDIR) {
|
||||
count += 2;
|
||||
|
||||
} else if (mtinfo.tag == LFSR_TAG_BRANCH) {
|
||||
} else if (tag == LFSR_TAG_BRANCH) {
|
||||
count += 1;
|
||||
|
||||
} else if (mtinfo.tag == LFSR_TAG_BLOCK) {
|
||||
} else if (tag == LFSR_TAG_BLOCK) {
|
||||
count += 1;
|
||||
|
||||
} else {
|
||||
@@ -12844,8 +12892,10 @@ int lfsr_traversal_read(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
}
|
||||
|
||||
// find next block
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
int err = lfsr_mtree_gc(lfs, t, &mtinfo);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
int err = lfsr_mtree_gc(lfs, t,
|
||||
&tag, &bptr);
|
||||
if (err) {
|
||||
// end of traversal?
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
@@ -12862,19 +12912,21 @@ int lfsr_traversal_read(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
}
|
||||
|
||||
// figure out type/blocks
|
||||
if (mtinfo.tag == LFSR_TAG_MDIR) {
|
||||
if (tag == LFSR_TAG_MDIR) {
|
||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
||||
t->o.o.flags = (t->o.o.flags & ~0x7) | LFS_BTYPE_MDIR;
|
||||
t->blocks[0] = mtinfo.u.mdir->rbyd.blocks[0];
|
||||
t->blocks[1] = mtinfo.u.mdir->rbyd.blocks[1];
|
||||
t->blocks[0] = mdir->rbyd.blocks[0];
|
||||
t->blocks[1] = mdir->rbyd.blocks[1];
|
||||
|
||||
} else if (mtinfo.tag == LFSR_TAG_BRANCH) {
|
||||
} else if (tag == LFSR_TAG_BRANCH) {
|
||||
t->o.o.flags = (t->o.o.flags & ~0x7) | LFS_BTYPE_BTREE;
|
||||
t->blocks[0] = mtinfo.u.rbyd->blocks[0];
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
||||
t->blocks[0] = rbyd->blocks[0];
|
||||
t->blocks[1] = -1;
|
||||
|
||||
} else if (mtinfo.tag == LFSR_TAG_BLOCK) {
|
||||
} else if (tag == LFSR_TAG_BLOCK) {
|
||||
t->o.o.flags = (t->o.o.flags & ~0x7) | LFS_BTYPE_DATA;
|
||||
t->blocks[0] = mtinfo.u.bptr.data.u.disk.block;
|
||||
t->blocks[0] = bptr.data.u.disk.block;
|
||||
t->blocks[1] = -1;
|
||||
|
||||
} else {
|
||||
|
||||
@@ -615,7 +615,7 @@ typedef struct lfsr_dir {
|
||||
|
||||
typedef struct lfsr_btraversal {
|
||||
lfsr_bid_t bid;
|
||||
lfsr_rbyd_t *branch;
|
||||
const lfsr_rbyd_t *branch;
|
||||
lfsr_srid_t rid;
|
||||
lfsr_rbyd_t rbyd;
|
||||
} lfsr_btraversal_t;
|
||||
|
||||
+64
-58
@@ -169,37 +169,38 @@ code = '''
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &mtinfo);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt,
|
||||
&tag, &bptr);
|
||||
assert(!err || err == LFS_ERR_NOENT);
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (mtinfo.tag == LFSR_TAG_MDIR) {
|
||||
if (tag == LFSR_TAG_MDIR) {
|
||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.mdir->rbyd.blocks[0],
|
||||
mtinfo.u.mdir->rbyd.blocks[1]);
|
||||
tag,
|
||||
mdir->rbyd.blocks[0],
|
||||
mdir->rbyd.blocks[1]);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[1] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[1] % 8);
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[0] % 8);
|
||||
seen[mdir->rbyd.blocks[1] / 8] |= 1 << (mdir->rbyd.blocks[1] % 8);
|
||||
seen[mdir->rbyd.blocks[0] / 8] |= 1 << (mdir->rbyd.blocks[0] % 8);
|
||||
|
||||
} else if (mtinfo.tag == LFSR_TAG_BRANCH) {
|
||||
} else if (tag == LFSR_TAG_BRANCH) {
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x btree 0x%x.%x\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.rbyd->blocks[0], mtinfo.u.rbyd->trunk);
|
||||
tag,
|
||||
rbyd->blocks[0], rbyd->trunk);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.rbyd->blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.rbyd->blocks[0] % 8);
|
||||
seen[rbyd->blocks[0] / 8] |= 1 << (rbyd->blocks[0] % 8);
|
||||
|
||||
} else {
|
||||
// this shouldn't happen
|
||||
printf("traversal: 0x%x\n", mtinfo.tag);
|
||||
printf("traversal: 0x%x\n", tag);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
@@ -337,46 +338,47 @@ code = '''
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &mtinfo);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt,
|
||||
&tag, &bptr);
|
||||
assert(!err || err == LFS_ERR_NOENT);
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (mtinfo.tag == LFSR_TAG_MDIR) {
|
||||
if (tag == LFSR_TAG_MDIR) {
|
||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.mdir->rbyd.blocks[0],
|
||||
mtinfo.u.mdir->rbyd.blocks[1]);
|
||||
tag,
|
||||
mdir->rbyd.blocks[0],
|
||||
mdir->rbyd.blocks[1]);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[1] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[1] % 8);
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[0] % 8);
|
||||
seen[mdir->rbyd.blocks[1] / 8] |= 1 << (mdir->rbyd.blocks[1] % 8);
|
||||
seen[mdir->rbyd.blocks[0] / 8] |= 1 << (mdir->rbyd.blocks[0] % 8);
|
||||
|
||||
} else if (mtinfo.tag == LFSR_TAG_BRANCH) {
|
||||
} else if (tag == LFSR_TAG_BRANCH) {
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x btree 0x%x.%x\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.rbyd->blocks[0], mtinfo.u.rbyd->trunk);
|
||||
tag,
|
||||
rbyd->blocks[0], rbyd->trunk);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.rbyd->blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.rbyd->blocks[0] % 8);
|
||||
seen[rbyd->blocks[0] / 8] |= 1 << (rbyd->blocks[0] % 8);
|
||||
|
||||
} else if (mtinfo.tag == LFSR_TAG_BLOCK) {
|
||||
} else if (tag == LFSR_TAG_BLOCK) {
|
||||
printf("traversal: 0x%x block 0x%x\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.bptr.data.u.disk.block);
|
||||
tag,
|
||||
bptr.data.u.disk.block);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.bptr.data.u.disk.block / 8]
|
||||
|= 1 << (mtinfo.u.bptr.data.u.disk.block % 8);
|
||||
seen[bptr.data.u.disk.block / 8]
|
||||
|= 1 << (bptr.data.u.disk.block % 8);
|
||||
|
||||
} else {
|
||||
// this shouldn't happen
|
||||
printf("traversal: 0x%x\n", mtinfo.tag);
|
||||
printf("traversal: 0x%x\n", tag);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
@@ -491,46 +493,50 @@ code = '''
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &mtinfo);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt,
|
||||
&tag, &bptr);
|
||||
assert(!err || err == LFS_ERR_NOENT);
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (mtinfo.tag == LFSR_TAG_MDIR) {
|
||||
if (tag == LFSR_TAG_MDIR) {
|
||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.mdir->rbyd.blocks[0],
|
||||
mtinfo.u.mdir->rbyd.blocks[1]);
|
||||
tag,
|
||||
mdir->rbyd.blocks[0],
|
||||
mdir->rbyd.blocks[1]);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[1] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[1] % 8);
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[0] % 8);
|
||||
seen[mdir->rbyd.blocks[1] / 8]
|
||||
|= 1 << (mdir->rbyd.blocks[1] % 8);
|
||||
seen[mdir->rbyd.blocks[0] / 8]
|
||||
|= 1 << (mdir->rbyd.blocks[0] % 8);
|
||||
|
||||
} else if (mtinfo.tag == LFSR_TAG_BRANCH) {
|
||||
} else if (tag == LFSR_TAG_BRANCH) {
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x btree 0x%x.%x\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.rbyd->blocks[0], mtinfo.u.rbyd->trunk);
|
||||
tag,
|
||||
rbyd->blocks[0], rbyd->trunk);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.rbyd->blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.rbyd->blocks[0] % 8);
|
||||
seen[rbyd->blocks[0] / 8]
|
||||
|= 1 << (rbyd->blocks[0] % 8);
|
||||
|
||||
} else if (mtinfo.tag == LFSR_TAG_BLOCK) {
|
||||
} else if (tag == LFSR_TAG_BLOCK) {
|
||||
printf("traversal: 0x%x block 0x%x\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.bptr.data.u.disk.block);
|
||||
tag,
|
||||
bptr.data.u.disk.block);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.bptr.data.u.disk.block / 8]
|
||||
|= 1 << (mtinfo.u.bptr.data.u.disk.block % 8);
|
||||
seen[bptr.data.u.disk.block / 8]
|
||||
|= 1 << (bptr.data.u.disk.block % 8);
|
||||
|
||||
} else {
|
||||
// this shouldn't happen
|
||||
printf("traversal: 0x%x\n", mtinfo.tag);
|
||||
printf("traversal: 0x%x\n", tag);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
+26
-22
@@ -4098,34 +4098,36 @@ code = '''
|
||||
assert(i <= 2*N);
|
||||
|
||||
lfsr_bid_t bid;
|
||||
lfsr_btinfo_t btinfo;
|
||||
int err = lfsr_btree_traverse(&lfs, &btree, &bt, &bid, &btinfo);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_data_t data;
|
||||
int err = lfsr_btree_traverse(&lfs, &btree, &bt,
|
||||
&bid, &tag, &data);
|
||||
assert(!err || err == LFS_ERR_NOENT);
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (btinfo.tag == LFSR_TAG_BRANCH) {
|
||||
if (tag == LFSR_TAG_BRANCH) {
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)data.u.buffer;
|
||||
printf("traversal: %d 0x%x btree 0x%x.%x\n",
|
||||
bid,
|
||||
btinfo.tag,
|
||||
btinfo.u.rbyd->blocks[0], btinfo.u.rbyd->trunk);
|
||||
tag,
|
||||
rbyd->blocks[0], rbyd->trunk);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[btinfo.u.rbyd->blocks[0] / 8]
|
||||
|= 1 << (btinfo.u.rbyd->blocks[0] % 8);
|
||||
seen[rbyd->blocks[0] / 8] |= 1 << (rbyd->blocks[0] % 8);
|
||||
|
||||
} else if (btinfo.tag == LFSR_TAG_DATA) {
|
||||
} else if (tag == LFSR_TAG_DATA) {
|
||||
printf("traversal: %d 0x%x data %d\n",
|
||||
bid,
|
||||
btinfo.tag,
|
||||
lfsr_data_size(btinfo.u.data));
|
||||
tag,
|
||||
lfsr_data_size(data));
|
||||
|
||||
} else {
|
||||
// well this shouldn't happen
|
||||
printf("traversal: %d 0x%x\n",
|
||||
bid,
|
||||
btinfo.tag);
|
||||
tag);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
@@ -4247,34 +4249,36 @@ code = '''
|
||||
assert(i <= 2*N);
|
||||
|
||||
lfsr_bid_t bid;
|
||||
lfsr_btinfo_t btinfo;
|
||||
int err = lfsr_btree_traverse(&lfs, &btree, &bt, &bid, &btinfo);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_data_t data;
|
||||
int err = lfsr_btree_traverse(&lfs, &btree, &bt,
|
||||
&bid, &tag, &data);
|
||||
assert(!err || err == LFS_ERR_NOENT);
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (btinfo.tag == LFSR_TAG_BRANCH) {
|
||||
if (tag == LFSR_TAG_BRANCH) {
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)data.u.buffer;
|
||||
printf("traversal: %d 0x%x btree 0x%x.%x\n",
|
||||
bid,
|
||||
btinfo.tag,
|
||||
btinfo.u.rbyd->blocks[0], btinfo.u.rbyd->trunk);
|
||||
tag,
|
||||
rbyd->blocks[0], rbyd->trunk);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[btinfo.u.rbyd->blocks[0] / 8]
|
||||
|= 1 << (btinfo.u.rbyd->blocks[0] % 8);
|
||||
seen[rbyd->blocks[0] / 8] |= 1 << (rbyd->blocks[0] % 8);
|
||||
|
||||
} else if (btinfo.tag == LFSR_TAG_DATA) {
|
||||
} else if (tag == LFSR_TAG_DATA) {
|
||||
printf("traversal: %d 0x%x data %d\n",
|
||||
bid,
|
||||
btinfo.tag,
|
||||
lfsr_data_size(btinfo.u.data));
|
||||
tag,
|
||||
lfsr_data_size(data));
|
||||
|
||||
} else {
|
||||
// well this shouldn't happen
|
||||
printf("traversal: %d 0x%x\n",
|
||||
bid,
|
||||
btinfo.tag);
|
||||
tag);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
+142
-122
@@ -3369,37 +3369,38 @@ code = '''
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &mtinfo);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt,
|
||||
&tag, &bptr);
|
||||
assert(!err || err == LFS_ERR_NOENT);
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (mtinfo.tag == LFSR_TAG_MDIR) {
|
||||
if (tag == LFSR_TAG_MDIR) {
|
||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.mdir->rbyd.blocks[0],
|
||||
mtinfo.u.mdir->rbyd.blocks[1]);
|
||||
tag,
|
||||
mdir->rbyd.blocks[0],
|
||||
mdir->rbyd.blocks[1]);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[1] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[1] % 8);
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[0] % 8);
|
||||
seen[mdir->rbyd.blocks[1] / 8] |= 1 << (mdir->rbyd.blocks[1] % 8);
|
||||
seen[mdir->rbyd.blocks[0] / 8] |= 1 << (mdir->rbyd.blocks[0] % 8);
|
||||
|
||||
} else if (mtinfo.tag == LFSR_TAG_BRANCH) {
|
||||
} else if (tag == LFSR_TAG_BRANCH) {
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x btree 0x%x.%x\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.rbyd->blocks[0], mtinfo.u.rbyd->trunk);
|
||||
tag,
|
||||
rbyd->blocks[0], rbyd->trunk);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.rbyd->blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.rbyd->blocks[0] % 8);
|
||||
seen[rbyd->blocks[0] / 8] |= 1 << (rbyd->blocks[0] % 8);
|
||||
|
||||
} else {
|
||||
// this shouldn't happen
|
||||
printf("traversal: 0x%x\n", mtinfo.tag);
|
||||
printf("traversal: 0x%x\n", tag);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
@@ -3484,37 +3485,38 @@ code = '''
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &mtinfo);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt,
|
||||
&tag, &bptr);
|
||||
assert(!err || err == LFS_ERR_NOENT);
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (mtinfo.tag == LFSR_TAG_MDIR) {
|
||||
if (tag == LFSR_TAG_MDIR) {
|
||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.mdir->rbyd.blocks[0],
|
||||
mtinfo.u.mdir->rbyd.blocks[1]);
|
||||
tag,
|
||||
mdir->rbyd.blocks[0],
|
||||
mdir->rbyd.blocks[1]);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[1] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[1] % 8);
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[0] % 8);
|
||||
seen[mdir->rbyd.blocks[1] / 8] |= 1 << (mdir->rbyd.blocks[1] % 8);
|
||||
seen[mdir->rbyd.blocks[0] / 8] |= 1 << (mdir->rbyd.blocks[0] % 8);
|
||||
|
||||
} else if (mtinfo.tag == LFSR_TAG_BRANCH) {
|
||||
} else if (tag == LFSR_TAG_BRANCH) {
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x btree 0x%x.%x\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.rbyd->blocks[0], mtinfo.u.rbyd->trunk);
|
||||
tag,
|
||||
rbyd->blocks[0], rbyd->trunk);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.rbyd->blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.rbyd->blocks[0] % 8);
|
||||
seen[rbyd->blocks[0] / 8] |= 1 << (rbyd->blocks[0] % 8);
|
||||
|
||||
} else {
|
||||
// this shouldn't happen
|
||||
printf("traversal: 0x%x\n", mtinfo.tag);
|
||||
printf("traversal: 0x%x\n", tag);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
@@ -3621,37 +3623,38 @@ code = '''
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &mtinfo);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt,
|
||||
&tag, &bptr);
|
||||
assert(!err || err == LFS_ERR_NOENT);
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (mtinfo.tag == LFSR_TAG_MDIR) {
|
||||
if (tag == LFSR_TAG_MDIR) {
|
||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.mdir->rbyd.blocks[0],
|
||||
mtinfo.u.mdir->rbyd.blocks[1]);
|
||||
tag,
|
||||
mdir->rbyd.blocks[0],
|
||||
mdir->rbyd.blocks[1]);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[1] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[1] % 8);
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[0] % 8);
|
||||
seen[mdir->rbyd.blocks[1] / 8] |= 1 << (mdir->rbyd.blocks[1] % 8);
|
||||
seen[mdir->rbyd.blocks[0] / 8] |= 1 << (mdir->rbyd.blocks[0] % 8);
|
||||
|
||||
} else if (mtinfo.tag == LFSR_TAG_BRANCH) {
|
||||
} else if (tag == LFSR_TAG_BRANCH) {
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x btree 0x%x.%x\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.rbyd->blocks[0], mtinfo.u.rbyd->trunk);
|
||||
tag,
|
||||
rbyd->blocks[0], rbyd->trunk);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.rbyd->blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.rbyd->blocks[0] % 8);
|
||||
seen[rbyd->blocks[0] / 8] |= 1 << (rbyd->blocks[0] % 8);
|
||||
|
||||
} else {
|
||||
// this shouldn't happen
|
||||
printf("traversal: 0x%x\n", mtinfo.tag);
|
||||
printf("traversal: 0x%x\n", tag);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
@@ -3779,37 +3782,38 @@ code = '''
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &mtinfo);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt,
|
||||
&tag, &bptr);
|
||||
assert(!err || err == LFS_ERR_NOENT);
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (mtinfo.tag == LFSR_TAG_MDIR) {
|
||||
if (tag == LFSR_TAG_MDIR) {
|
||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.mdir->rbyd.blocks[0],
|
||||
mtinfo.u.mdir->rbyd.blocks[1]);
|
||||
tag,
|
||||
mdir->rbyd.blocks[0],
|
||||
mdir->rbyd.blocks[1]);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[1] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[1] % 8);
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[0] % 8);
|
||||
seen[mdir->rbyd.blocks[1] / 8] |= 1 << (mdir->rbyd.blocks[1] % 8);
|
||||
seen[mdir->rbyd.blocks[0] / 8] |= 1 << (mdir->rbyd.blocks[0] % 8);
|
||||
|
||||
} else if (mtinfo.tag == LFSR_TAG_BRANCH) {
|
||||
} else if (tag == LFSR_TAG_BRANCH) {
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x btree 0x%x.%x\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.rbyd->blocks[0], mtinfo.u.rbyd->trunk);
|
||||
tag,
|
||||
rbyd->blocks[0], rbyd->trunk);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.rbyd->blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.rbyd->blocks[0] % 8);
|
||||
seen[rbyd->blocks[0] / 8] |= 1 << (rbyd->blocks[0] % 8);
|
||||
|
||||
} else {
|
||||
// this shouldn't happen
|
||||
printf("traversal: 0x%x\n", mtinfo.tag);
|
||||
printf("traversal: 0x%x\n", tag);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
@@ -3921,37 +3925,41 @@ code = '''
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &mtinfo);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt,
|
||||
&tag, &bptr);
|
||||
assert(!err || err == LFS_ERR_NOENT);
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (mtinfo.tag == LFSR_TAG_MDIR) {
|
||||
if (tag == LFSR_TAG_MDIR) {
|
||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.mdir->rbyd.blocks[0],
|
||||
mtinfo.u.mdir->rbyd.blocks[1]);
|
||||
tag,
|
||||
mdir->rbyd.blocks[0],
|
||||
mdir->rbyd.blocks[1]);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[1] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[1] % 8);
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[0] % 8);
|
||||
seen[mdir->rbyd.blocks[1] / 8]
|
||||
|= 1 << (mdir->rbyd.blocks[1] % 8);
|
||||
seen[mdir->rbyd.blocks[0] / 8]
|
||||
|= 1 << (mdir->rbyd.blocks[0] % 8);
|
||||
|
||||
} else if (mtinfo.tag == LFSR_TAG_BRANCH) {
|
||||
} else if (tag == LFSR_TAG_BRANCH) {
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x btree 0x%x.%x\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.rbyd->blocks[0], mtinfo.u.rbyd->trunk);
|
||||
tag,
|
||||
rbyd->blocks[0], rbyd->trunk);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.rbyd->blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.rbyd->blocks[0] % 8);
|
||||
seen[rbyd->blocks[0] / 8]
|
||||
|= 1 << (rbyd->blocks[0] % 8);
|
||||
|
||||
} else {
|
||||
// this shouldn't happen
|
||||
printf("traversal: 0x%x\n", mtinfo.tag);
|
||||
printf("traversal: 0x%x\n", tag);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
@@ -4038,37 +4046,41 @@ code = '''
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &mtinfo);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt,
|
||||
&tag, &bptr);
|
||||
assert(!err || err == LFS_ERR_NOENT);
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (mtinfo.tag == LFSR_TAG_MDIR) {
|
||||
if (tag == LFSR_TAG_MDIR) {
|
||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.mdir->rbyd.blocks[0],
|
||||
mtinfo.u.mdir->rbyd.blocks[1]);
|
||||
tag,
|
||||
mdir->rbyd.blocks[0],
|
||||
mdir->rbyd.blocks[1]);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[1] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[1] % 8);
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[0] % 8);
|
||||
seen[mdir->rbyd.blocks[1] / 8]
|
||||
|= 1 << (mdir->rbyd.blocks[1] % 8);
|
||||
seen[mdir->rbyd.blocks[0] / 8]
|
||||
|= 1 << (mdir->rbyd.blocks[0] % 8);
|
||||
|
||||
} else if (mtinfo.tag == LFSR_TAG_BRANCH) {
|
||||
} else if (tag == LFSR_TAG_BRANCH) {
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x btree 0x%x.%x\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.rbyd->blocks[0], mtinfo.u.rbyd->trunk);
|
||||
tag,
|
||||
rbyd->blocks[0], rbyd->trunk);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.rbyd->blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.rbyd->blocks[0] % 8);
|
||||
seen[rbyd->blocks[0] / 8]
|
||||
|= 1 << (rbyd->blocks[0] % 8);
|
||||
|
||||
} else {
|
||||
// this shouldn't happen
|
||||
printf("traversal: 0x%x\n", mtinfo.tag);
|
||||
printf("traversal: 0x%x\n", tag);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
@@ -4197,37 +4209,41 @@ code = '''
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &mtinfo);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt,
|
||||
&tag, &bptr);
|
||||
assert(!err || err == LFS_ERR_NOENT);
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (mtinfo.tag == LFSR_TAG_MDIR) {
|
||||
if (tag == LFSR_TAG_MDIR) {
|
||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.mdir->rbyd.blocks[0],
|
||||
mtinfo.u.mdir->rbyd.blocks[1]);
|
||||
tag,
|
||||
mdir->rbyd.blocks[0],
|
||||
mdir->rbyd.blocks[1]);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[1] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[1] % 8);
|
||||
seen[mtinfo.u.mdir->rbyd.blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.mdir->rbyd.blocks[0] % 8);
|
||||
seen[mdir->rbyd.blocks[1] / 8]
|
||||
|= 1 << (mdir->rbyd.blocks[1] % 8);
|
||||
seen[mdir->rbyd.blocks[0] / 8]
|
||||
|= 1 << (mdir->rbyd.blocks[0] % 8);
|
||||
|
||||
} else if (mtinfo.tag == LFSR_TAG_BRANCH) {
|
||||
} else if (tag == LFSR_TAG_BRANCH) {
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x btree 0x%x.%x\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.rbyd->blocks[0], mtinfo.u.rbyd->trunk);
|
||||
tag,
|
||||
rbyd->blocks[0], rbyd->trunk);
|
||||
|
||||
// keep track of seen blocks
|
||||
seen[mtinfo.u.rbyd->blocks[0] / 8]
|
||||
|= 1 << (mtinfo.u.rbyd->blocks[0] % 8);
|
||||
seen[rbyd->blocks[0] / 8]
|
||||
|= 1 << (rbyd->blocks[0] % 8);
|
||||
|
||||
} else {
|
||||
// this shouldn't happen
|
||||
printf("traversal: 0x%x\n", mtinfo.tag);
|
||||
printf("traversal: 0x%x\n", tag);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
@@ -4319,27 +4335,31 @@ code = '''
|
||||
// assert that we detect the cycle in a reasonable number of iterations
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &mtinfo);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt,
|
||||
&tag, &bptr);
|
||||
assert(!err || err == LFS_ERR_CORRUPT);
|
||||
if (err == LFS_ERR_CORRUPT) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (mtinfo.tag == LFSR_TAG_MDIR) {
|
||||
if (tag == LFSR_TAG_MDIR) {
|
||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.mdir->rbyd.blocks[0],
|
||||
mtinfo.u.mdir->rbyd.blocks[1]);
|
||||
tag,
|
||||
mdir->rbyd.blocks[0],
|
||||
mdir->rbyd.blocks[1]);
|
||||
|
||||
} else if (mtinfo.tag == LFSR_TAG_BRANCH) {
|
||||
} else if (tag == LFSR_TAG_BRANCH) {
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
||||
printf("traversal: 0x%x btree 0x%x.%x\n",
|
||||
mtinfo.tag,
|
||||
mtinfo.u.rbyd->blocks[0], mtinfo.u.rbyd->trunk);
|
||||
tag,
|
||||
rbyd->blocks[0], rbyd->trunk);
|
||||
|
||||
} else {
|
||||
// this shouldn't happen
|
||||
printf("traversal: 0x%x\n", mtinfo.tag);
|
||||
printf("traversal: 0x%x\n", tag);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
+80
-60
@@ -6077,12 +6077,14 @@ code = '''
|
||||
// we need internals to check this
|
||||
// ckmeta needed for eoff
|
||||
lfsr_mtraversal_t mt = LFSR_MTRAVERSAL(LFS_T_CKMETA);
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &mtinfo) => 0;
|
||||
assert(mtinfo.tag == LFSR_TAG_MDIR);
|
||||
lfsr_mtree_traverse(&lfs, &mt, &mtinfo) => 0;
|
||||
assert(mtinfo.tag == LFSR_TAG_BRANCH);
|
||||
if (lfsr_rbyd_eoff(mtinfo.u.rbyd) > GC_COMPACT_THRESH) {
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr) => 0;
|
||||
assert(tag == LFSR_TAG_MDIR);
|
||||
lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr) => 0;
|
||||
assert(tag == LFSR_TAG_BRANCH);
|
||||
if (lfsr_rbyd_eoff((lfsr_rbyd_t*)bptr.data.u.buffer)
|
||||
> GC_COMPACT_THRESH) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -6135,12 +6137,14 @@ code = '''
|
||||
|
||||
// mtree should have been compacted
|
||||
lfsr_mtraversal_t mt = LFSR_MTRAVERSAL(LFS_T_CKMETA);
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &mtinfo) => 0;
|
||||
assert(mtinfo.tag == LFSR_TAG_MDIR);
|
||||
lfsr_mtree_traverse(&lfs, &mt, &mtinfo) => 0;
|
||||
assert(mtinfo.tag == LFSR_TAG_BRANCH);
|
||||
assert(lfsr_rbyd_eoff(mtinfo.u.rbyd) <= GC_COMPACT_THRESH);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr) => 0;
|
||||
assert(tag == LFSR_TAG_MDIR);
|
||||
lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr) => 0;
|
||||
assert(tag == LFSR_TAG_BRANCH);
|
||||
assert(lfsr_rbyd_eoff((lfsr_rbyd_t*)bptr.data.u.buffer)
|
||||
<= GC_COMPACT_THRESH);
|
||||
|
||||
// check we can still read the files
|
||||
for (int remount = 0; remount < 2; remount++) {
|
||||
@@ -6555,12 +6559,14 @@ code = '''
|
||||
// we need internals to check this
|
||||
// ckmeta needed for eoff
|
||||
lfsr_mtraversal_t mt = LFSR_MTRAVERSAL(LFS_T_CKMETA);
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &mtinfo) => 0;
|
||||
assert(mtinfo.tag == LFSR_TAG_MDIR);
|
||||
lfsr_mtree_traverse(&lfs, &mt, &mtinfo) => 0;
|
||||
assert(mtinfo.tag == LFSR_TAG_BRANCH);
|
||||
if (lfsr_rbyd_eoff(mtinfo.u.rbyd) > GC_COMPACT_THRESH) {
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr) => 0;
|
||||
assert(tag == LFSR_TAG_MDIR);
|
||||
lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr) => 0;
|
||||
assert(tag == LFSR_TAG_BRANCH);
|
||||
if (lfsr_rbyd_eoff((lfsr_rbyd_t*)bptr.data.u.buffer)
|
||||
> GC_COMPACT_THRESH) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -6600,17 +6606,19 @@ code = '''
|
||||
|
||||
// bshrub should have been compacted
|
||||
lfsr_mtraversal_t mt = LFSR_MTRAVERSAL(LFS_T_CKMETA);
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &mtinfo) => 0;
|
||||
assert(mtinfo.tag == LFSR_TAG_MDIR);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr) => 0;
|
||||
assert(tag == LFSR_TAG_MDIR);
|
||||
while (true) {
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &mtinfo);
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr);
|
||||
assert(!err || err == LFS_ERR_NOENT);
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
}
|
||||
assert(mtinfo.tag == LFSR_TAG_BRANCH);
|
||||
assert(lfsr_rbyd_eoff(mtinfo.u.rbyd) <= GC_COMPACT_THRESH);
|
||||
assert(tag == LFSR_TAG_BRANCH);
|
||||
assert(lfsr_rbyd_eoff((lfsr_rbyd_t*)bptr.data.u.buffer)
|
||||
<= GC_COMPACT_THRESH);
|
||||
}
|
||||
|
||||
// check we can still read the file
|
||||
@@ -6668,12 +6676,14 @@ code = '''
|
||||
// we need internals to check this
|
||||
// ckmeta needed for eoff
|
||||
lfsr_mtraversal_t mt = LFSR_MTRAVERSAL(LFS_T_CKMETA);
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &mtinfo) => 0;
|
||||
assert(mtinfo.tag == LFSR_TAG_MDIR);
|
||||
lfsr_mtree_traverse(&lfs, &mt, &mtinfo) => 0;
|
||||
assert(mtinfo.tag == LFSR_TAG_BRANCH);
|
||||
if (lfsr_rbyd_eoff(mtinfo.u.rbyd) > GC_COMPACT_THRESH) {
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr) => 0;
|
||||
assert(tag == LFSR_TAG_MDIR);
|
||||
lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr) => 0;
|
||||
assert(tag == LFSR_TAG_BRANCH);
|
||||
if (lfsr_rbyd_eoff((lfsr_rbyd_t*)bptr.data.u.buffer)
|
||||
> GC_COMPACT_THRESH) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -6713,17 +6723,19 @@ code = '''
|
||||
|
||||
// bshrub should have been compacted
|
||||
lfsr_mtraversal_t mt = LFSR_MTRAVERSAL(LFS_T_CKMETA);
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &mtinfo) => 0;
|
||||
assert(mtinfo.tag == LFSR_TAG_MDIR);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr) => 0;
|
||||
assert(tag == LFSR_TAG_MDIR);
|
||||
while (true) {
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &mtinfo);
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr);
|
||||
assert(!err || err == LFS_ERR_NOENT);
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
}
|
||||
assert(mtinfo.tag == LFSR_TAG_BRANCH);
|
||||
assert(lfsr_rbyd_eoff(mtinfo.u.rbyd) <= GC_COMPACT_THRESH);
|
||||
assert(tag == LFSR_TAG_BRANCH);
|
||||
assert(lfsr_rbyd_eoff((lfsr_rbyd_t*)bptr.data.u.buffer)
|
||||
<= GC_COMPACT_THRESH);
|
||||
}
|
||||
|
||||
// check we can still read the file
|
||||
@@ -6782,12 +6794,14 @@ code = '''
|
||||
// we need internals to check this
|
||||
// ckmeta needed for eoff
|
||||
lfsr_mtraversal_t mt = LFSR_MTRAVERSAL(LFS_T_CKMETA);
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &mtinfo) => 0;
|
||||
assert(mtinfo.tag == LFSR_TAG_MDIR);
|
||||
lfsr_mtree_traverse(&lfs, &mt, &mtinfo) => 0;
|
||||
assert(mtinfo.tag == LFSR_TAG_BRANCH);
|
||||
if (lfsr_rbyd_eoff(mtinfo.u.rbyd) > GC_COMPACT_THRESH) {
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr) => 0;
|
||||
assert(tag == LFSR_TAG_MDIR);
|
||||
lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr) => 0;
|
||||
assert(tag == LFSR_TAG_BRANCH);
|
||||
if (lfsr_rbyd_eoff((lfsr_rbyd_t*)bptr.data.u.buffer)
|
||||
> GC_COMPACT_THRESH) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -6825,17 +6839,19 @@ code = '''
|
||||
|
||||
// bshrub should have been compacted
|
||||
lfsr_mtraversal_t mt = LFSR_MTRAVERSAL(LFS_T_CKMETA);
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &mtinfo) => 0;
|
||||
assert(mtinfo.tag == LFSR_TAG_MDIR);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr) => 0;
|
||||
assert(tag == LFSR_TAG_MDIR);
|
||||
while (true) {
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &mtinfo);
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr);
|
||||
assert(!err || err == LFS_ERR_NOENT);
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
}
|
||||
assert(mtinfo.tag == LFSR_TAG_BRANCH);
|
||||
assert(lfsr_rbyd_eoff(mtinfo.u.rbyd) <= GC_COMPACT_THRESH);
|
||||
assert(tag == LFSR_TAG_BRANCH);
|
||||
assert(lfsr_rbyd_eoff((lfsr_rbyd_t*)bptr.data.u.buffer)
|
||||
<= GC_COMPACT_THRESH);
|
||||
}
|
||||
|
||||
// check we can still read the file
|
||||
@@ -6894,12 +6910,14 @@ code = '''
|
||||
// we need internals to check this
|
||||
// ckmeta needed for eoff
|
||||
lfsr_mtraversal_t mt = LFSR_MTRAVERSAL(LFS_T_CKMETA);
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &mtinfo) => 0;
|
||||
assert(mtinfo.tag == LFSR_TAG_MDIR);
|
||||
lfsr_mtree_traverse(&lfs, &mt, &mtinfo) => 0;
|
||||
assert(mtinfo.tag == LFSR_TAG_BRANCH);
|
||||
if (lfsr_rbyd_eoff(mtinfo.u.rbyd) > GC_COMPACT_THRESH) {
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr) => 0;
|
||||
assert(tag == LFSR_TAG_MDIR);
|
||||
lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr) => 0;
|
||||
assert(tag == LFSR_TAG_BRANCH);
|
||||
if (lfsr_rbyd_eoff((lfsr_rbyd_t*)bptr.data.u.buffer)
|
||||
> GC_COMPACT_THRESH) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -6958,17 +6976,19 @@ code = '''
|
||||
|
||||
// bshrub should have been compacted
|
||||
lfsr_mtraversal_t mt = LFSR_MTRAVERSAL(LFS_T_CKMETA);
|
||||
lfsr_mtinfo_t mtinfo;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &mtinfo) => 0;
|
||||
assert(mtinfo.tag == LFSR_TAG_MDIR);
|
||||
lfsr_tag_t tag;
|
||||
lfsr_bptr_t bptr;
|
||||
lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr) => 0;
|
||||
assert(tag == LFSR_TAG_MDIR);
|
||||
while (true) {
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &mtinfo);
|
||||
int err = lfsr_mtree_traverse(&lfs, &mt, &tag, &bptr);
|
||||
assert(!err || err == LFS_ERR_NOENT);
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
}
|
||||
assert(mtinfo.tag == LFSR_TAG_BRANCH);
|
||||
assert(lfsr_rbyd_eoff(mtinfo.u.rbyd) <= GC_COMPACT_THRESH);
|
||||
assert(tag == LFSR_TAG_BRANCH);
|
||||
assert(lfsr_rbyd_eoff((lfsr_rbyd_t*)bptr.data.u.buffer)
|
||||
<= GC_COMPACT_THRESH);
|
||||
}
|
||||
|
||||
// check we can still read the files
|
||||
|
||||
Reference in New Issue
Block a user