bmap: The initial bmapcache algorithm seems to be working

At least at a proof-of-concept level, there's still a lot of cleanup
needed.

To make things work, lfs3_alloc_ckpoint now takes an mdir, which
provides the target for gbmap gstate updates.

When the bmap is close to empty (configurable via bmap_scan_thresh), we
opportunistically rebuild it during lfs3_alloc_ckpoints. The nice thing
about lfs3_alloc_ckpoint is we know the state of all in-flight blocks,
so rebuilding the bmap just requires traversing the filesystem + in-RAM
state.

We might still fall back to the lookahead buffer, but in theory a well
tuned bmap_scan_thresh can prevent this from becoming a bottleneck (at
the cost of more frequent bmap rebuilds).

---

This is also probably a good time to resume measuring code/ram costs,
though it's worth repeating the above note about the bmap work still
needing cleanup:

             code          stack          ctx
  before:   36840           2368          684
  after:    36920 (+0.2%)   2368 (+0.0%)  684 (+0.0%)

Haha, no, the bmap isn't basically free, it's just an opt-in features.
With -DLFS3_YES_BMAP=1:

             code          stack          ctx
  no bmap:  36920           2368          684
  yes bmap: 38552 (+4.4%)   2472 (+4.4%)  812 (+18.7%)
This commit is contained in:
Christopher Haster
2025-07-28 23:27:02 -05:00
parent 8666830515
commit 316ca1cc05
17 changed files with 329 additions and 135 deletions
+173 -24
View File
@@ -2380,7 +2380,7 @@ static inline bool lfs3_alloc_iserase(uint32_t flags) {
// blocks are allocated at most once, and never reallocated, between
// checkpoints
#if !defined(LFS3_RDONLY)
static inline void lfs3_alloc_ckpoint(lfs3_t *lfs3);
static inline void lfs3_alloc_ckpoint(lfs3_t *lfs3, lfs3_mdir_t *mdir);
#endif
// discard any lookahead state, this is necessary if block_count changes
@@ -10421,7 +10421,7 @@ static int lfs3_mdir_mkconsistent(lfs3_t *lfs3, lfs3_mdir_t *mdir);
static void lfs3_alloc_markfree(lfs3_t *lfs3, lfs3_block_t known);
// high-level mutating traversal, handle extra features that require
// mutation here, upper layers should call lfs3_alloc_ckpoint as needed
// mutation here
static lfs3_stag_t lfs3_mtree_gc(lfs3_t *lfs3, lfs3_trv_t *trv,
lfs3_bptr_t *bptr_) {
dropped:;
@@ -10494,7 +10494,7 @@ dropped:;
: lfs3->cfg->block_size - lfs3->cfg->block_size/8);
// checkpoint the allocator
lfs3_alloc_ckpoint(lfs3);
lfs3_alloc_ckpoint(lfs3, mdir);
// compact the mdir
err = lfs3_mdir_compact(lfs3, mdir);
if (err) {
@@ -10756,6 +10756,41 @@ static int lfs3_bmap_set(lfs3_t *lfs3, lfs3_btree_t *bmap,
}
#endif
#ifdef LFS3_BMAP
static int lfs3_bmap_setbptr(lfs3_t *lfs3, lfs3_btree_t *bmap,
lfs3_tag_t tag, const lfs3_bptr_t *bptr,
lfs3_tag_t tag_) {
const lfs3_block_t *blocks;
lfs3_size_t block_count;
if (tag == LFS3_TAG_MDIR) {
lfs3_mdir_t *mdir = (lfs3_mdir_t*)bptr->d.u.buffer;
blocks = mdir->r.blocks;
block_count = 2;
} else if (tag == LFS3_TAG_BRANCH) {
lfs3_rbyd_t *rbyd = (lfs3_rbyd_t*)bptr->d.u.buffer;
blocks = rbyd->blocks;
block_count = 1;
} else if (tag == LFS3_TAG_BLOCK) {
blocks = &bptr->d.u.disk.block;
block_count = 1;
} else {
LFS3_UNREACHABLE();
}
for (lfs3_size_t i = 0; i < block_count; i++) {
int err = lfs3_bmap_set(lfs3, bmap, blocks[i], tag_);
if (err) {
return err;
}
}
return 0;
}
#endif
// TODO lfs3_bmap_relocate
// TODO lfs3_bmap_mdirdiff
// TODO lfs3_bmap_btreediff
@@ -10764,6 +10799,9 @@ static int lfs3_bmap_set(lfs3_t *lfs3, lfs3_btree_t *bmap,
/// Block allocator ///
// needed in lfs3_alloc_ckpoint
static int lfs3_alloc_rebuildbmap(lfs3_t *lfs3, lfs3_mdir_t *mdir);
// checkpoint the allocator
//
// operations that need to alloc should call this when all in-use blocks
@@ -10772,9 +10810,19 @@ static int lfs3_bmap_set(lfs3_t *lfs3, lfs3_btree_t *bmap,
// blocks are allocated at most once, and never reallocated, between
// checkpoints
#if !defined(LFS3_RDONLY)
static inline void lfs3_alloc_ckpoint(lfs3_t *lfs3) {
static inline void lfs3_alloc_ckpoint(lfs3_t *lfs3, lfs3_mdir_t *mdir) {
#ifndef LFS3_2BONLY
lfs3->lookahead.ckpoint = lfs3->block_count;
#ifdef LFS3_BMAP
// do we need to rebuild the bmap?
if (lfs3->lookahead.bmapped < lfs3_min(
lfs3->cfg->bmap_scan_thresh,
lfs3->block_count)) {
int err = lfs3_alloc_rebuildbmap(lfs3, mdir);
// TODO lfs3_alloc_ckpoint should propagate errors
LFS3_ASSERT(!err);
}
#endif
#else
(void)lfs3;
#endif
@@ -11221,6 +11269,98 @@ static lfs3_sblock_t lfs3_alloc(lfs3_t *lfs3, uint32_t flags) {
}
#endif
#ifdef LFS3_BMAP
// the mdir argument does two things here:
// 1. offloads wear from the mroot a bit
// 2. broadcasts erased-state updates correctly
//
// if NULL, we just commit to the mroot, and mroot chain extension can
// take over if the wear gets too bad
static int lfs3_alloc_rebuildbmap(lfs3_t *lfs3, lfs3_mdir_t *mdir) {
// we should ckpoint before calling this
LFS3_ASSERT(lfs3->lookahead.ckpoint == lfs3->cfg->block_count);
LFS3_INFO("Rebuilding bmap "
"(bmap %"PRId32"/%"PRId32"/%"PRId32")",
lfs3->lookahead.bmapped,
lfs3->lookahead.ckpoint,
lfs3->cfg->block_count);
lfs3_block_t bmapped = lfs3->lookahead.bmapped;
// create a new bmap
lfs3_btree_t bmap_;
lfs3_btree_init(&bmap_);
int err = lfs3_bmap_commit(lfs3, &bmap_, 0, LFS3_RATTRS(
LFS3_RATTR(LFS3_TAG_BMFREE, +lfs3->cfg->block_count)));
if (err) {
goto failed;
}
// traverse the filesystem, building up knowledge of what blocks are
// in-use
//
// TODO should we also copy over bad/erased blocks from the old bmap?
// TODO should we just copy the old bmap and manually clear in-use
// blocks? we're already doing a O(n) scan of the filesystem anyways
//
lfs3_trv_t trv;
lfs3_trv_init(&trv, LFS3_T_RDONLY | LFS3_T_LOOKAHEAD);
while (true) {
lfs3_bptr_t bptr;
lfs3_stag_t tag = lfs3_mtree_traverse(lfs3, &trv,
&bptr);
if (tag < 0) {
if (tag == LFS3_ERR_NOENT) {
break;
}
return tag;
}
// track in-use blocks
err = lfs3_bmap_setbptr(lfs3, &bmap_, tag, &bptr,
LFS3_TAG_BMINUSE);
if (err) {
goto failed;
}
}
// commit the new bmap into gstate
//
// lfs3_mdir_commit may immediately allocate from the bmap before it
// even hits the, but this is fine, lfs3_mdir_commit updates
// window/known with alloc progress before any internal commits
//
// also note lfs3_mdir_commit reverts to on-disk state on failure
// lfs3->gbmap.window = (lfs3->lookahead.window + lfs3->lookahead.off)
// % lfs3->cfg->block_count;
// lfs3->gbmap.known = ((lfs3->lookahead.ckpoint + lfs3->cfg->block_count)
// - lfs3->gbmap.window)
// % lfs3->cfg->block_count;
lfs3->lookahead.bmapped = lfs3->lookahead.ckpoint;
lfs3->gbmap.b = bmap_;
err = lfs3_mdir_commit(lfs3, (mdir) ? mdir : &lfs3->mroot, NULL, 0);
if (err) {
goto failed;
}
return 0;
failed:;
// not having enough space for the bmap isn't really an error
if (err == LFS3_ERR_NOSPC) {
LFS3_INFO("Not enough space for bmap "
"(lookahead %"PRId32"/%"PRId32"/%"PRId32")",
lfs3->lookahead.known,
lfs3->lookahead.ckpoint,
lfs3->cfg->block_count);
return 0;
}
// revert bmapped on error
lfs3->lookahead.bmapped = bmapped;
return err;
}
#endif
@@ -11346,7 +11486,7 @@ int lfs3_mkdir(lfs3_t *lfs3, const char *path) {
// mid updates, since the mid technically doesn't exist yet...
// commit our bookmark and a grm to self-remove in case of powerloss
lfs3_alloc_ckpoint(lfs3);
lfs3_alloc_ckpoint(lfs3, &mdir);
err = lfs3_mdir_commit(lfs3, &mdir, LFS3_RATTRS(
LFS3_RATTR_NAME(
LFS3_TAG_BOOKMARK, +1, did_, NULL, 0),
@@ -11368,10 +11508,13 @@ int lfs3_mkdir(lfs3_t *lfs3, const char *path) {
? tag_ >= 0
: tag_ == LFS3_ERR_NOENT);
// TODO should we have a GRMPOP rattr? to match GRMPUSH? The fact that
// lfs3_mdir_commit implicitly reverts grms is a bit counterintuitive
//
// commit our new directory into our parent, zeroing the grm in the
// process
lfs3_alloc_ckpoint(lfs3, &mdir);
lfs3_grm_pop(lfs3);
lfs3_alloc_ckpoint(lfs3);
err = lfs3_mdir_commit(lfs3, &mdir, LFS3_RATTRS(
LFS3_RATTR_NAME(
LFS3_TAG_MASK12 | LFS3_TAG_DIR,
@@ -11517,7 +11660,7 @@ int lfs3_remove(lfs3_t *lfs3, const char *path) {
bool zombie = lfs3_mid_isopen(lfs3, mdir.mid, -1);
// remove the metadata entry
lfs3_alloc_ckpoint(lfs3);
lfs3_alloc_ckpoint(lfs3, &mdir);
err = lfs3_mdir_commit(lfs3, &mdir, LFS3_RATTRS(
// create a stickynote if zombied
//
@@ -11574,6 +11717,9 @@ int lfs3_remove(lfs3_t *lfs3, const char *path) {
// this up to lfs3_fs_fixgrm
err = lfs3_fs_fixgrm(lfs3);
if (err) {
// TODO is this the right thing to do? we should probably still
// propagate errors to the user
//
// we did complete the remove, so we shouldn't error here, best
// we can do is log this
LFS3_WARN("Failed to clean up grm (%d)", err);
@@ -11695,7 +11841,7 @@ int lfs3_rename(lfs3_t *lfs3, 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
lfs3_alloc_ckpoint(lfs3);
lfs3_alloc_ckpoint(lfs3, &new_mdir);
err = lfs3_mdir_commit(lfs3, &new_mdir, LFS3_RATTRS(
LFS3_RATTR_NAME(
LFS3_TAG_MASK12 | old_tag,
@@ -11757,6 +11903,9 @@ int lfs3_rename(lfs3_t *lfs3, const char *old_path, const char *new_path) {
// this up to lfs3_fs_fixgrm
err = lfs3_fs_fixgrm(lfs3);
if (err) {
// TODO is this the right thing to do? we should probably still
// propagate errors to the user
//
// we did complete the remove, so we shouldn't error here, best
// we can do is log this
LFS3_WARN("Failed to clean up grm (%d)", err);
@@ -12133,7 +12282,7 @@ int lfs3_setattr(lfs3_t *lfs3, const char *path, uint8_t type,
}
// commit our attr
lfs3_alloc_ckpoint(lfs3);
lfs3_alloc_ckpoint(lfs3, &mdir);
err = lfs3_mdir_commit(lfs3, &mdir, LFS3_RATTRS(
LFS3_RATTR_DATA(
LFS3_TAG_ATTR(type), 0,
@@ -12189,7 +12338,7 @@ int lfs3_removeattr(lfs3_t *lfs3, const char *path, uint8_t type) {
}
// commit our removal
lfs3_alloc_ckpoint(lfs3);
lfs3_alloc_ckpoint(lfs3, &mdir);
err = lfs3_mdir_commit(lfs3, &mdir, LFS3_RATTRS(
LFS3_RATTR(
LFS3_TAG_RM | LFS3_TAG_ATTR(type), 0)));
@@ -12488,7 +12637,7 @@ int lfs3_file_opencfg_(lfs3_t *lfs3, lfs3_file_t *file,
} else {
// create a stickynote entry if we don't have one, this
// reserves the mid until first sync
lfs3_alloc_ckpoint(lfs3);
lfs3_alloc_ckpoint(lfs3, &file->b.h.mdir);
err = lfs3_mdir_commit(lfs3, &file->b.h.mdir, LFS3_RATTRS(
LFS3_RATTR_NAME(
LFS3_TAG_STICKYNOTE, +1,
@@ -13441,7 +13590,7 @@ static int lfs3_file_crystallize(lfs3_t *lfs3, lfs3_file_t *file) {
LFS3_ASSERT(lfs3_o_isunsync(file->b.h.flags));
// checkpoint the allocator
lfs3_alloc_ckpoint(lfs3);
lfs3_alloc_ckpoint(lfs3, &file->b.h.mdir);
// finish crystallizing
int err = lfs3_file_crystallize_(lfs3, file,
file->leaf.pos - lfs3_bptr_off(&file->leaf.bptr), -1, -1,
@@ -13463,7 +13612,7 @@ static int lfs3_file_flushset_(lfs3_t *lfs3, lfs3_file_t *file,
lfs3_off_t pos = 0;
while (size > 0) {
// checkpoint the allocator
lfs3_alloc_ckpoint(lfs3);
lfs3_alloc_ckpoint(lfs3, &file->b.h.mdir);
// enough data for a block?
#ifndef LFS3_2BONLY
@@ -13563,7 +13712,7 @@ static int lfs3_file_flush_(lfs3_t *lfs3, lfs3_file_t *file,
#ifndef LFS3_2BONLY
while (size > 0) {
// checkpoint the allocator
lfs3_alloc_ckpoint(lfs3);
lfs3_alloc_ckpoint(lfs3, &file->b.h.mdir);
// mid-crystallization? can we just resume crystallizing?
//
@@ -13812,7 +13961,7 @@ fragment:;
// iteratively write fragments (inlined leaves)
while (size > 0) {
// checkpoint the allocator
lfs3_alloc_ckpoint(lfs3);
lfs3_alloc_ckpoint(lfs3, &file->b.h.mdir);
// do we need to discard our leaf? we need to discard fragments
// in case the underlying rbyd compacts, and we need to discard
@@ -14310,7 +14459,7 @@ static int lfs3_file_sync_(lfs3_t *lfs3, lfs3_file_t *file,
// make sure we don't overflow our rattr buffer
LFS3_ASSERT(rattr_count <= sizeof(rattrs)/sizeof(lfs3_rattr_t));
// checkpoint the allocator
lfs3_alloc_ckpoint(lfs3);
lfs3_alloc_ckpoint(lfs3, &file->b.h.mdir);
// and commit!
int err = lfs3_mdir_commit(lfs3, &file->b.h.mdir,
rattrs, rattr_count);
@@ -14606,7 +14755,7 @@ int lfs3_file_truncate(lfs3_t *lfs3, lfs3_file_t *file, lfs3_off_t size_) {
file->b.h.flags |= LFS3_o_UNSYNC;
// checkpoint the allocator
lfs3_alloc_ckpoint(lfs3);
lfs3_alloc_ckpoint(lfs3, &file->b.h.mdir);
// truncate our btree
err = lfs3_file_graft_(lfs3, file,
lfs3_min(size, size_), size - lfs3_min(size, size_),
@@ -14688,7 +14837,7 @@ int lfs3_file_fruncate(lfs3_t *lfs3, lfs3_file_t *file, lfs3_off_t size_) {
file->b.h.flags |= LFS3_o_UNSYNC;
// checkpoint the allocator
lfs3_alloc_ckpoint(lfs3);
lfs3_alloc_ckpoint(lfs3, &file->b.h.mdir);
// fruncate our btree
err = lfs3_file_graft_(lfs3, file,
0, lfs3_smax(size - size_, 0),
@@ -16423,10 +16572,10 @@ static int lfs3_fs_fixgrm(lfs3_t *lfs3) {
// we need to revert manually on error
lfs3_grm_t grm_p = lfs3->grm;
// checkpoint the allocator
lfs3_alloc_ckpoint(lfs3, &mdir);
// mark grm as taken care of
lfs3_grm_pop(lfs3);
// checkpoint the allocator
lfs3_alloc_ckpoint(lfs3);
// remove the rid while atomically updating our grm
err = lfs3_mdir_commit(lfs3, &mdir, LFS3_RATTRS(
LFS3_RATTR(LFS3_TAG_RM, -1)));
@@ -16479,7 +16628,7 @@ static int lfs3_mdir_mkconsistent(lfs3_t *lfs3, lfs3_mdir_t *mdir) {
lfs3_dbgmrid(lfs3, mdir->mid));
// checkpoint the allocator
lfs3_alloc_ckpoint(lfs3);
lfs3_alloc_ckpoint(lfs3, mdir);
// remove the orphaned stickynote
err = lfs3_mdir_commit(lfs3, mdir, LFS3_RATTRS(
LFS3_RATTR(LFS3_TAG_RM, -1)));
@@ -16632,7 +16781,7 @@ static int lfs3_fs_gc_(lfs3_t *lfs3, lfs3_trv_t *trv,
while (pending && (lfs3_off_t)steps > 0) {
// checkpoint the allocator to maximize any lookahead scans
#ifndef LFS3_RDONLY
lfs3_alloc_ckpoint(lfs3);
lfs3_alloc_ckpoint(lfs3, NULL);
#endif
// start a new traversal?
@@ -16772,7 +16921,7 @@ int lfs3_fs_grow(lfs3_t *lfs3, lfs3_size_t block_count_) {
lfs3_alloc_discard(lfs3);
// update our on-disk config
lfs3_alloc_ckpoint(lfs3);
lfs3_alloc_ckpoint(lfs3, NULL);
int err = lfs3_mdir_commit(lfs3, &lfs3->mroot, LFS3_RATTRS(
LFS3_RATTR_GEOMETRY(
LFS3_TAG_GEOMETRY, 0,
@@ -16871,7 +17020,7 @@ int lfs3_trv_read(lfs3_t *lfs3, lfs3_trv_t *trv,
// checkpoint the allocator to maximize any lookahead scans
#ifndef LFS3_RDONLY
lfs3_alloc_ckpoint(lfs3);
lfs3_alloc_ckpoint(lfs3, NULL);
#endif
while (true) {
+11
View File
@@ -568,6 +568,17 @@ struct lfs3_cfg {
#ifndef LFS3_RDONLY
lfs3_size_t crystal_thresh;
#endif
// Threshold for when to rebuild block-map information. littlefs
// will attempt to rebuild the block-map when fewer than this many
// blocks are known. Larger values rebuild the block-map more
// frequently, reducing the chance of falling back to a slower
// allocator at a performance cost.
//
// 0 only rebuilds the block-map when empty.
#ifdef LFS3_BMAP
lfs3_block_t bmap_scan_thresh;
#endif
};
// File info structure
+3 -1
View File
@@ -121,6 +121,7 @@ void bench_permutation(size_t i, uint32_t *buffer, size_t size);
BENCH_DEFINE(INLINE_SIZE, BLOCK_SIZE/4 ) \
BENCH_DEFINE(FRAGMENT_SIZE, LFS3_MIN(BLOCK_SIZE/8, 512) ) \
BENCH_DEFINE(CRYSTAL_THRESH, BLOCK_SIZE/8 ) \
BENCH_DEFINE(BMAP_SCAN_THRESH, BLOCK_COUNT/4 ) \
BENCH_DEFINE(ERASE_VALUE, 0xff ) \
BENCH_DEFINE(ERASE_CYCLES, 0 ) \
BENCH_DEFINE(BADBLOCK_BEHAVIOR, LFS3_EMUBD_BADBLOCK_PROGERROR ) \
@@ -154,7 +155,8 @@ void bench_permutation(size_t i, uint32_t *buffer, size_t size);
#ifdef LFS3_BMAP
#define BENCH_BMAP_CFG \
.treediff_size = TREEDIFF_SIZE,
.treediff_size = TREEDIFF_SIZE, \
.bmap_scan_thresh = BMAP_SCAN_THRESH,
#else
#define BENCH_BMAP_CFG
#endif
+3 -1
View File
@@ -112,6 +112,7 @@ void test_permutation(size_t i, uint32_t *buffer, size_t size);
TEST_DEFINE(INLINE_SIZE, BLOCK_SIZE/4 ) \
TEST_DEFINE(FRAGMENT_SIZE, LFS3_MIN(BLOCK_SIZE/8, 512) ) \
TEST_DEFINE(CRYSTAL_THRESH, BLOCK_SIZE/8 ) \
TEST_DEFINE(BMAP_SCAN_THRESH, BLOCK_COUNT/4 ) \
TEST_DEFINE(ERASE_VALUE, 0xff ) \
TEST_DEFINE(ERASE_CYCLES, 0 ) \
TEST_DEFINE(BADBLOCK_BEHAVIOR, LFS3_EMUBD_BADBLOCK_PROGERROR ) \
@@ -145,7 +146,8 @@ void test_permutation(size_t i, uint32_t *buffer, size_t size);
#ifdef LFS3_BMAP
#define TEST_BMAP_CFG \
.treediff_size = TREEDIFF_SIZE,
.treediff_size = TREEDIFF_SIZE, \
.bmap_scan_thresh = BMAP_SCAN_THRESH,
#else
#define TEST_BMAP_CFG
#endif
+6 -3
View File
@@ -9,6 +9,9 @@
#
after = ['test_mtree', 'test_bmap', 'test_dirs', 'test_files']
# TODO bmap workaround?
ifndef = 'LFS3_BMAP'
# test that we can alloc
[cases.test_alloc_alloc]
defines.COUNT = [
@@ -30,7 +33,7 @@ code = '''
lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
// start allocating
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_size_t alloced = 0;
while (true) {
lfs3_sblock_t block = lfs3_alloc(&lfs3, ERASE);
@@ -74,7 +77,7 @@ code = '''
lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
// start allocating
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_size_t alloced = 0;
while (true) {
lfs3_sblock_t block = lfs3_alloc(&lfs3, ERASE);
@@ -95,7 +98,7 @@ code = '''
assert(alloced == COUNT-2);
// ack again, effectively releasing all the previously alloced blocks
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
alloced = 0;
while (true) {
lfs3_sblock_t block = lfs3_alloc(&lfs3, ERASE);
+6 -3
View File
@@ -11,6 +11,9 @@ after = [
'test_compat',
]
# TODO bmap workaround?
ifndef = 'LFS3_BMAP'
## Single-block badblock tests
#
@@ -58,7 +61,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a btree
lfs3_btree_t btree;
@@ -2013,7 +2016,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a btree
lfs3_btree_t btree;
@@ -3970,7 +3973,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a btree
lfs3_btree_t btree;
+6 -6
View File
@@ -9,7 +9,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create an initial bmap
lfs3_btree_t bmap;
@@ -70,7 +70,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create an initial bmap
lfs3_btree_t bmap;
@@ -135,7 +135,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create an initial bmap
lfs3_btree_t bmap;
@@ -201,7 +201,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create an initial bmap
lfs3_btree_t bmap;
@@ -268,7 +268,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create an initial bmap
lfs3_btree_t bmap;
@@ -318,7 +318,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create an initial bmap
lfs3_btree_t bmap;
+53 -50
View File
@@ -1,6 +1,9 @@
# Test the mid-level B-trees
after = 'test_rbyd'
# TODO bmap workaround?
ifndef = 'LFS3_BMAP'
# maximize lookahead buffer, we don't actually gc so we only get one pass
# of the disk for these tests
defines.LOOKAHEAD_SIZE = '(BLOCK_COUNT+8-1) / 8'
@@ -17,7 +20,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create an empty tree
lfs3_btree_t btree;
@@ -49,7 +52,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a single-entry tree
lfs3_btree_t btree;
@@ -93,7 +96,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a two-entry tree
lfs3_btree_t btree;
@@ -144,7 +147,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a two-entry tree
lfs3_btree_t btree;
@@ -196,7 +199,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a two-entry tree
lfs3_btree_t btree;
@@ -256,7 +259,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a two-entry tree
lfs3_btree_t btree;
@@ -319,7 +322,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a tree with N elements
lfs3_btree_t btree;
@@ -371,7 +374,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a tree with N elements
lfs3_btree_t btree;
@@ -425,7 +428,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a btree
lfs3_btree_t btree;
@@ -509,7 +512,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a tree with N elements
lfs3_btree_t btree;
@@ -579,7 +582,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a btree
lfs3_btree_t btree;
@@ -717,7 +720,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a single-entry tree
lfs3_btree_t btree;
@@ -764,7 +767,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a two-entry tree
lfs3_btree_t btree;
@@ -824,7 +827,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a two-entry tree
lfs3_btree_t btree;
@@ -898,7 +901,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a tree with N elements
lfs3_btree_t btree;
@@ -957,7 +960,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a btree
lfs3_btree_t btree;
@@ -1045,7 +1048,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a tree with N elements
lfs3_btree_t btree;
@@ -1120,7 +1123,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a btree
lfs3_btree_t btree;
@@ -1265,7 +1268,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a single-entry tree
lfs3_btree_t btree;
@@ -1323,7 +1326,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a single-entry tree
lfs3_btree_t btree;
@@ -1397,7 +1400,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a single-entry tree
lfs3_btree_t btree;
@@ -1471,7 +1474,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a single-entry tree
lfs3_btree_t btree;
@@ -1564,7 +1567,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a tree with N elements
lfs3_btree_t btree;
@@ -1645,7 +1648,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a tree with N elements
lfs3_btree_t btree;
@@ -1729,7 +1732,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a btree
lfs3_btree_t btree;
@@ -1819,7 +1822,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a tree with N elements
lfs3_btree_t btree;
@@ -1927,7 +1930,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a btree
lfs3_btree_t btree;
@@ -2079,7 +2082,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a tree with N elements
lfs3_btree_t btree;
@@ -2140,7 +2143,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a btree
lfs3_btree_t btree;
@@ -2231,7 +2234,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a tree with N elements
lfs3_btree_t btree;
@@ -2293,7 +2296,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a btree
lfs3_btree_t btree;
@@ -2473,7 +2476,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a tree
lfs3_btree_t btree;
@@ -2544,7 +2547,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a tree
lfs3_btree_t btree;
@@ -2618,7 +2621,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a tree
lfs3_btree_t btree;
@@ -2685,7 +2688,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a tree
lfs3_btree_t btree;
@@ -2769,7 +2772,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a btree
lfs3_btree_t btree;
@@ -2877,7 +2880,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a btree
lfs3_btree_t btree;
@@ -3044,7 +3047,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a zero-entry tree
lfs3_btree_t btree;
@@ -3076,7 +3079,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a single-entry tree
lfs3_btree_t btree;
@@ -3135,7 +3138,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a two-entry tree
lfs3_btree_t btree;
@@ -3211,7 +3214,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a two-entry tree
lfs3_btree_t btree;
@@ -3304,7 +3307,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a two-entry tree
lfs3_btree_t btree;
@@ -3398,7 +3401,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a tree with N elements
lfs3_btree_t btree;
@@ -3475,7 +3478,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a btree
lfs3_btree_t btree;
@@ -3593,7 +3596,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a tree with N elements
lfs3_btree_t btree;
@@ -3671,7 +3674,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a btree
lfs3_btree_t btree;
@@ -3830,7 +3833,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a btree
lfs3_btree_t btree;
@@ -4010,7 +4013,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a btree
lfs3_btree_t btree;
@@ -4238,7 +4241,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a tree with N elements
lfs3_btree_t btree;
@@ -4366,7 +4369,7 @@ code = '''
lfs3.lookahead.off = 0;
lfs3.lookahead.known = lfs3_min(8*CFG->lookahead_size,
CFG->block_count-2);
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create a btree
lfs3_btree_t btree;
+3
View File
@@ -1,6 +1,9 @@
# Test checksum validation things
after = ['test_trvs', 'test_gc', 'test_mount']
# TODO bmap workaround?
ifndef = 'LFS3_BMAP'
code = '''
// naive crc32c
+3
View File
@@ -4,6 +4,9 @@
# are needed to validate the directory tree works
after = 'test_dirs'
# TODO bmap workaround?
ifndef = 'LFS3_BMAP'
# test some dir functions
+1 -1
View File
@@ -1226,7 +1226,7 @@ code = '''
lfs3_file_sync(&lfs3, &file) => 0;
// create an empty btree
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_rbyd_alloc(&lfs3, &file.b.shrub.r) => 0;
lfs3_rbyd_commit(&lfs3, &file.b.shrub.r, 0, LFS3_RATTRS(
LFS3_RATTR_BUF(LFS3_TAG_DATA, +1, "?", 1))) => 0;
+3
View File
@@ -4,6 +4,9 @@
# GC-API specific things here
after = ['test_trvs']
# TODO bmap workaround?
ifndef = 'LFS3_BMAP'
# test that lookahead can make progress in isolation
[cases.test_gc_lookahead_progress]
defines.CKMETA = [false, true]
+3
View File
@@ -8,6 +8,9 @@ after = [
'test_mount',
]
# TODO bmap workaround?
ifndef = 'LFS3_BMAP'
# test we can mount a filesystem with fewer blocks
[cases.test_grow_mount_smaller]
+3
View File
@@ -1,6 +1,9 @@
# Advanced mount tests
after = ['test_mtree', 'test_trvs']
# TODO bmap workaround?
ifndef = 'LFS3_BMAP'
# test we can mount
[cases.test_mount_simple]
+46 -46
View File
@@ -42,7 +42,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
for (lfs3_size_t i = 0; i < N; i++) {
lfs3_mdir_commit(&lfs3, &lfs3.mroot, LFS3_RATTRS(
@@ -86,7 +86,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
for (lfs3_size_t i = 0; i < N; i++) {
// force mroot to compact
@@ -133,7 +133,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
for (lfs3_size_t i = 0; i < N; i++) {
lfs3_mdir_commit(&lfs3, &lfs3.mroot, LFS3_RATTRS(
@@ -182,7 +182,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// create a 2 large rattrs that needs to be uninlined
@@ -265,7 +265,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// create 2 large entries that needs to be uninlined and split
@@ -360,7 +360,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// create 2 large entries that needs to be uninlined and split
@@ -501,7 +501,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create entries
for (lfs3_size_t i = 0; i < N; i++) {
@@ -588,7 +588,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
bool sim[N];
for (lfs3_size_t i = 0; i < N; i++) {
@@ -697,7 +697,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// create 2 large entries that needs to be uninlined and split
@@ -791,7 +791,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// create 2 large entries that needs to be uninlined and split
@@ -887,7 +887,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// create 2 large entries that needs to be uninlined and split
@@ -964,7 +964,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// create 2 large entries that needs to be uninlined and split
@@ -1084,7 +1084,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// create 2 large entries that needs to be uninlined and split
@@ -1206,7 +1206,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
bool sim[N];
for (lfs3_size_t i = 0; i < N; i++) {
@@ -1343,7 +1343,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// create a 2 large rattrs that needs to be uninlined
@@ -1469,7 +1469,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// create 2 large entries that needs to be uninlined and split
@@ -1609,7 +1609,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// create 2 large entries that needs to be uninlined and split
@@ -1749,7 +1749,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// prepare mroot with an entry
@@ -1832,7 +1832,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// prepare mroot with an entry
@@ -1970,7 +1970,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// prepare mroot with an entry
@@ -2081,7 +2081,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// create 2 large entries that needs to be uninlined and split
@@ -2226,7 +2226,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// create 2 large entries that needs to be uninlined and split
@@ -2388,7 +2388,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// create 2 large entries that needs to be uninlined and split
@@ -2495,7 +2495,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// force mroot to compact once, so the second compact below will
// trigger a relocation
@@ -2588,7 +2588,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// force mroot to compact once, so the second compact below will
// trigger a relocation
@@ -2695,7 +2695,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
bool sim[N];
for (lfs3_size_t i = 0; i < N; i++) {
@@ -2857,7 +2857,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// setup our neighbors
lfs3_handle_t left = {.flags=0};
@@ -2917,7 +2917,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// setup our neighbors
lfs3_handle_t left = {.flags=0};
@@ -2967,7 +2967,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// setup our neighbors
lfs3_handle_t left = {.flags=0};
@@ -3019,7 +3019,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// setup our neighbors
lfs3_handle_t left = {.flags=0};
@@ -3096,7 +3096,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// setup our neighbors
lfs3_handle_t left = {.flags=0};
@@ -3187,7 +3187,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// setup our neighbors
lfs3_handle_t left = {.flags=0};
@@ -3245,7 +3245,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// setup our neighbors
lfs3_handle_t left = {.flags=0};
@@ -3342,7 +3342,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// setup our neighbors
lfs3_handle_t left = {.flags=0};
@@ -3437,7 +3437,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// setup our neighbors
lfs3_handle_t left = {.flags=0};
@@ -3547,7 +3547,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// setup our neighbors
lfs3_handle_t left = {.flags=0};
@@ -3651,7 +3651,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// insert at least one entry
lfs3_mdir_t mdir;
@@ -3757,7 +3757,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// create a 2 large rattrs that needs to be uninlined
@@ -3897,7 +3897,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// create 2 large entries that needs to be uninlined and split
@@ -4049,7 +4049,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// create 2 large entries that needs to be uninlined and split
@@ -4234,7 +4234,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// insert at least one entry
lfs3_mdir_t mdir;
@@ -4353,7 +4353,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
// create entries
for (lfs3_size_t i = 0; i < N; i++) {
@@ -4505,7 +4505,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
bool sim[N];
for (lfs3_size_t i = 0; i < N; i++) {
@@ -4678,7 +4678,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_mdir_commit(&lfs3, &lfs3.mroot, LFS3_RATTRS(
LFS3_RATTR_MPTR(
@@ -4998,7 +4998,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// prepare mroot with an entry
@@ -5058,7 +5058,7 @@ code = '''
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR | F_FLAGS, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR | M_FLAGS, CFG) => 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_alloc_ckpoint(&lfs3, NULL);
lfs3_data_t data;
// prepare mroot with an entry
+3
View File
@@ -7,6 +7,9 @@ after = [
'test_powerloss',
]
# TODO bmap workaround?
ifndef = 'LFS3_BMAP'
# Note that most of the delicate relocation operations are already tested
# in test_mtree. This mostly just covers high-level operations with
# relatively aggressive wear-leveling.
+3
View File
@@ -7,6 +7,9 @@ after = [
'test_alloc'
]
# TODO bmap workaround?
ifndef = 'LFS3_BMAP'
# a simple traversal test
[cases.test_trvs_simple]
defines.MKCONSISTENT = [false, true]