Reimplemented the block-allocator over mtree traversal

Took the opportunity to make some allocator tweaks:

- Renamed lfs.free -> lfs.lookahead, it's previous name did cause some
  confusion.

- Renamed lfs.free.off -> lfs.lookahead.start
- Renamed lfs.free.i   -> lfs.lookahead.next
- Renamed lfs.free.ack -> lfs.lookahead.acked

- Changed bitmap from using 32-bit words to using 8-bit bytes, dropping
  the alignment requirement. One of the reasons for 32-bit alignment was
  an attempt at future proofing for some sort of free-list.

  This never landed, and if it did, it could have been provided without
  breaking backwards compatiblity via an additional config option, at a
  minor RAM cost.

  We never used ffs/clz instructions for this bitmap, so I don't think
  using 32-bit words offers much advantage. It just creates another
  potential issue for users if their lookahead buffer is unaligned.

These changes should probably also be upstreamed to the current version.
They don't depend on anything rbyd specific.

Note, at some point lfs_alloc will need to be extended to mark block tags,
etc, as in-use during traversal.
This commit is contained in:
Christopher Haster
2023-06-29 18:02:47 -05:00
parent 91d90b7eef
commit eee0e6cfa1
5 changed files with 540 additions and 306 deletions
+126 -113
View File
@@ -1459,93 +1459,13 @@ static lfs_ssize_t lfsr_fcrc_fromdisk(lfs_t *lfs, lfsr_fcrc_t *fcrc,
// int (*cb)(void *data, lfs_block_t block), void *data,
// bool includeorphans);
static int lfs_deinit(lfs_t *lfs);
//static int lfs_deinit(lfs_t *lfs);
//static int lfs_rawunmount(lfs_t *lfs);
/// Block allocator ///
//#ifndef LFS_READONLY
//static int lfs_alloc_lookahead(void *p, lfs_block_t block) {
// lfs_t *lfs = (lfs_t*)p;
// lfs_block_t off = ((block - lfs->free.off)
// + lfs->cfg->block_count) % lfs->cfg->block_count;
//
// if (off < lfs->free.size) {
// lfs->free.buffer[off / 32] |= 1U << (off % 32);
// }
//
// return 0;
//}
//#endif
// indicate allocated blocks have been committed into the filesystem, this
// is to prevent blocks from being garbage collected in the middle of a
// commit operation
static void lfs_alloc_ack(lfs_t *lfs) {
lfs->free.ack = lfs->cfg->block_count;
}
//// drop the lookahead buffer, this is done during mounting and failed
//// traversals in order to avoid invalid lookahead state
//static void lfs_alloc_drop(lfs_t *lfs) {
// lfs->free.size = 0;
// lfs->free.i = 0;
// lfs_alloc_ack(lfs);
//}
#ifndef LFS_READONLY
static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
while (true) {
while (lfs->free.i != lfs->free.size) {
lfs_block_t off = lfs->free.i;
lfs->free.i += 1;
lfs->free.ack -= 1;
if (!(lfs->free.buffer[off / 32] & (1U << (off % 32)))) {
// found a free block
*block = (lfs->free.off + off) % lfs->cfg->block_count;
// eagerly find next off so an alloc ack can
// discredit old lookahead blocks
while (lfs->free.i != lfs->free.size &&
(lfs->free.buffer[lfs->free.i / 32]
& (1U << (lfs->free.i % 32)))) {
lfs->free.i += 1;
lfs->free.ack -= 1;
}
return 0;
}
}
// TODO implement this eventually
LFS_ERROR("No more free space %"PRIu32,
lfs->free.i + lfs->free.off);
return LFS_ERR_NOSPC;
// // check if we have looked at all blocks since last ack
// if (lfs->free.ack == 0) {
// LFS_ERROR("No more free space %"PRIu32,
// lfs->free.i + lfs->free.off);
// return LFS_ERR_NOSPC;
// }
//
// lfs->free.off = (lfs->free.off + lfs->free.size)
// % lfs->cfg->block_count;
// lfs->free.size = lfs_min(8*lfs->cfg->lookahead_size, lfs->free.ack);
// lfs->free.i = 0;
//
// // find mask of free blocks from tree
// memset(lfs->free.buffer, 0, lfs->cfg->lookahead_size);
// int err = lfs_fs_rawtraverse(lfs, lfs_alloc_lookahead, lfs, true);
// if (err) {
// lfs_alloc_drop(lfs);
// return err;
// }
}
}
#endif
// predeclare block allocator functions
static int lfs_alloc(lfs_t *lfs, lfs_block_t *block);
static void lfs_alloc_ack(lfs_t *lfs);
/// Red-black-yellow Dhara tree operations ///
@@ -6281,6 +6201,14 @@ static int lfsr_mountinited(lfs_t *lfs) {
}
}
// once we've mounted and derived a pseudo-random seed, initialize our
// block allocator
//
// the purpose of this is to avoid bad wear patterns such as always
// allocating blocks near the beginning of disk after a power-loss
//
lfs->lookahead.start = lfs->seed % lfs->cfg->block_count;
return 0;
}
@@ -6329,17 +6257,6 @@ int lfsr_mount(lfs_t *lfs, const struct lfs_config *cfg) {
return err;
}
// TODO this is a big hack to scaffold things until we have a working
// block allocator
//
// create free lookahead
memset(lfs->free.buffer, 0, lfs->cfg->lookahead_size);
lfs->free.off = 0;
lfs->free.size = lfs_min(8*lfs->cfg->lookahead_size,
lfs->cfg->block_count);
lfs->free.i = 2;
lfs_alloc_ack(lfs);
err = lfsr_mountinited(lfs);
if (err) {
// make sure we clean up on error
@@ -6360,17 +6277,6 @@ int lfsr_format(lfs_t *lfs, const struct lfs_config *cfg) {
return err;
}
// TODO this is a big hack to scaffold things until we have a working
// block allocator
//
// create free lookahead
memset(lfs->free.buffer, 0, lfs->cfg->lookahead_size);
lfs->free.off = 0;
lfs->free.size = lfs_min(8*lfs->cfg->lookahead_size,
lfs->cfg->block_count);
lfs->free.i = 2;
lfs_alloc_ack(lfs);
err = lfsr_formatinited(lfs);
if (err) {
// make sure we clean up on error
@@ -6383,6 +6289,110 @@ int lfsr_format(lfs_t *lfs, const struct lfs_config *cfg) {
/// Block allocator ///
// Allocations should call this when all allocated blocks are committed to the
// filesystem, either in the mtree or in tracked mdirs. After an ack, the block
// allocator may realloc any untracked blocks.
static void lfs_alloc_ack(lfs_t *lfs) {
lfs->lookahead.acked = lfs->cfg->block_count;
}
static inline void lfs_alloc_setinuse(lfs_t *lfs, lfs_block_t block) {
// translate to lookahead-relative
lfs_block_t rel = ((block + lfs->cfg->block_count) - lfs->lookahead.start)
% lfs->cfg->block_count;
if (rel < lfs->lookahead.size) {
// mark as in-use
lfs->lookahead.buffer[rel / 8] |= 1 << (rel % 8);
}
}
static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
while (true) {
// scan our lookahead buffer for free blocks
while (lfs->lookahead.next < lfs->lookahead.size) {
if (!(lfs->lookahead.buffer[lfs->lookahead.next / 8]
& (1 << (lfs->lookahead.next % 8)))) {
// found a free block
*block = (lfs->lookahead.start + lfs->lookahead.next)
% lfs->cfg->block_count;
// eagerly find next free block to maximize how many blocks
// lfs_alloc_ack makes available for scanning
while (true) {
lfs->lookahead.next += 1;
lfs->lookahead.acked -= 1;
if (lfs->lookahead.next >= lfs->lookahead.size
|| !(lfs->lookahead.buffer[lfs->lookahead.next / 8]
& (1 << (lfs->lookahead.next % 8)))) {
return 0;
}
}
}
lfs->lookahead.next += 1;
lfs->lookahead.acked -= 1;
}
// In order to keep our block allocator from spinning forever when our
// filesystem is full, we mark points where there are no in-flight
// allocations with an "ack" before starting a set of allocaitons.
//
// If we've looked at all blocks since the last ack, we report the
// filesystem as out of storage.
//
if (lfs->lookahead.acked <= 0) {
LFS_ERROR("No more free space 0x%"PRIx32,
(lfs->lookahead.start + lfs->lookahead.next)
% lfs->cfg->block_count);
return LFS_ERR_NOSPC;
}
// No blocks in our lookahead buffer, we need to scan the filesystem for
// unused blocks in the next lookahead window.
//
// note we limit the lookahead window to at most the amount of blocks
// acked, this prevents the above math from underflowing
//
lfs->lookahead.start += lfs->lookahead.size;
lfs->lookahead.next = 0;
lfs->lookahead.size = lfs_min32(
8*lfs->cfg->lookahead_size,
lfs->lookahead.acked);
memset(lfs->lookahead.buffer, 0, lfs->cfg->lookahead_size);
// traverse the filesystem, building up knowledge of what blocks are
// in use in our lookahead window
lfsr_mtree_traversal_t traversal = LFSR_MTREE_TRAVERSAL_INIT(0);
while (true) {
lfsr_tag_t tag;
lfsr_data_t data;
int err = lfsr_mtree_traversal_next(lfs, &traversal,
NULL, &tag, &data);
if (err && err != LFS_ERR_NOENT) {
return err;
}
if (err == LFS_ERR_NOENT) {
break;
}
// TODO add block pointers here?
// mark any blocks we see at in-use, including any btree/mdir blocks
if (tag == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data.buf.buffer;
lfs_alloc_setinuse(lfs, mdir->rbyd.block);
lfs_alloc_setinuse(lfs, mdir->redund_block);
} else if (tag == LFSR_TAG_BTREE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t*)data.buf.buffer;
lfs_alloc_setinuse(lfs, branch->block);
}
}
}
}
///// Metadata pair and directory operations ///
@@ -9811,19 +9821,22 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
lfs_cache_zero(lfs, &lfs->rcache);
lfs_cache_zero(lfs, &lfs->pcache);
// setup lookahead, must be multiple of 64-bits, 32-bit aligned
// setup lookahead buffer, note mount finishes initializing this after
// we establish a decent pseudo-random seed
LFS_ASSERT(lfs->cfg->lookahead_size > 0);
LFS_ASSERT(lfs->cfg->lookahead_size % 8 == 0 &&
(uintptr_t)lfs->cfg->lookahead_buffer % 4 == 0);
if (lfs->cfg->lookahead_buffer) {
lfs->free.buffer = lfs->cfg->lookahead_buffer;
lfs->lookahead.buffer = lfs->cfg->lookahead_buffer;
} else {
lfs->free.buffer = lfs_malloc(lfs->cfg->lookahead_size);
if (!lfs->free.buffer) {
lfs->lookahead.buffer = lfs_malloc(lfs->cfg->lookahead_size);
if (!lfs->lookahead.buffer) {
err = LFS_ERR_NOMEM;
goto cleanup;
}
}
lfs->lookahead.start = 0;
lfs->lookahead.size = 0;
lfs->lookahead.next = 0;
lfs->lookahead.acked = 0;
// check that the size limits are sane
LFS_ASSERT(lfs->cfg->name_max <= LFS_NAME_MAX);
@@ -9878,7 +9891,7 @@ static int lfs_deinit(lfs_t *lfs) {
}
if (!lfs->cfg->lookahead_buffer) {
lfs_free(lfs->free.buffer);
lfs_free(lfs->lookahead.buffer);
}
return 0;
+8 -9
View File
@@ -241,9 +241,8 @@ struct lfs_config {
// By default lfs_malloc is used to allocate this buffer.
void *prog_buffer;
// Optional statically allocated lookahead buffer. Must be lookahead_size
// and aligned to a 32-bit boundary. By default lfs_malloc is used to
// allocate this buffer.
// Optional statically allocated lookahead buffer. Must be lookahead_size.
// By default lfs_malloc is used to allocate this buffer.
void *lookahead_buffer;
// Optional upper limit on length of file names in bytes. No downside for
@@ -461,13 +460,13 @@ typedef struct lfs {
lfs_gstate_t gdisk;
lfs_gstate_t gdelta;
struct lfs_free {
lfs_block_t off;
struct lfs_lookahead {
lfs_block_t start;
lfs_block_t size;
lfs_block_t i;
lfs_block_t ack;
uint32_t *buffer;
} free;
lfs_block_t next;
lfs_block_t acked;
uint8_t *buffer;
} lookahead;
const struct lfs_config *cfg;
lfs_size_t name_max;
+174
View File
@@ -1,3 +1,177 @@
# Tests covering properties of the block allocator
# TODO test all of these with weird block sizes? would be nice to make this
# easy via the test_runner, either by handling it there or letting a single
# config limit the block count by a couple blocks
# test that we can alloc
[cases.test_alloc_blocks]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
// start allocating
lfs_alloc_ack(&lfs);
lfs_size_t alloced = 0;
while (true) {
lfs_block_t block;
int err = lfs_alloc(&lfs, &block);
assert(!err || err == LFS_ERR_NOSPC);
if (err == LFS_ERR_NOSPC) {
break;
}
alloced += 1;
// our allocator should stop at some point...
assert(alloced < 2*BLOCK_COUNT);
}
// excluding our mroot, we should have allocated exactly
// block_count-2 blocks
printf("alloced %d/%d blocks\n", alloced, (lfs_block_t)BLOCK_COUNT);
assert(alloced == BLOCK_COUNT-2);
lfsr_unmount(&lfs) => 0;
'''
# test that we can realloc after an ack
[cases.test_alloc_reuse]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
// start allocating
lfs_alloc_ack(&lfs);
lfs_size_t alloced = 0;
while (true) {
lfs_block_t block;
int err = lfs_alloc(&lfs, &block);
assert(!err || err == LFS_ERR_NOSPC);
if (err == LFS_ERR_NOSPC) {
break;
}
alloced += 1;
// our allocator should stop at some point...
assert(alloced < 2*BLOCK_COUNT);
}
// excluding our mroot, we should have allocated exactly
// block_count-2 blocks
printf("alloced %d/%d blocks\n", alloced, (lfs_block_t)BLOCK_COUNT);
assert(alloced == BLOCK_COUNT-2);
// ack again, effectively releasing all the previously alloced blocks
lfs_alloc_ack(&lfs);
alloced = 0;
while (true) {
lfs_block_t block;
int err = lfs_alloc(&lfs, &block);
assert(!err || err == LFS_ERR_NOSPC);
if (err == LFS_ERR_NOSPC) {
break;
}
alloced += 1;
// our allocator should stop at some point...
assert(alloced < 2*BLOCK_COUNT);
}
// excluding our mroot, we should have allocated exactly
// block_count-2 blocks
printf("alloced %d/%d blocks\n", alloced, (lfs_block_t)BLOCK_COUNT);
assert(alloced == BLOCK_COUNT-2);
lfsr_unmount(&lfs) => 0;
'''
# test that we can alloc an mtree, the difference between this and mtree tests
# is we expect this to be able to handle wrap-around
[cases.test_alloc_mtree]
in = 'lfs.c'
code = '''
const char *alphas = "abcdefghijklmnopqrstuvwxyz";
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfsr_mdir_t mdir;
lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, &mdir) => 0;
lfs_ssize_t rid = 0;
lfs_size_t count = 0;
while (true) {
// at least try to catch infinite loops
assert(count < BLOCK_SIZE * BLOCK_COUNT/2);
// ack before each commit to reset the allocator
lfs_alloc_ack(&lfs);
// keep creating new metadata entries until we run out of space
int err = lfsr_mdir_commit(&lfs, &mdir, &rid, LFSR_ATTRS(
LFSR_ATTR(rid, INLINED, +1, &alphas[count % 26], 1)));
assert(!err || err == LFS_ERR_NOSPC);
if (err == LFS_ERR_NOSPC) {
break;
}
uint8_t buffer[4];
lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED,
buffer, 4) => 1;
assert(memcmp(buffer, &alphas[count % 26], 1) == 0);
count += 1;
rid += 1;
}
printf("alloced %d metadata entries in %d blocks\n",
count, (lfs_block_t)BLOCK_COUNT);
// test that all of our metadata entries are still there
lfs_size_t i = 0;
for (lfs_ssize_t mid = (lfsr_mtree_isinlined(&lfs) ? -1 : 0);
mid < lfsr_mtree_weight(&lfs);
mid++) {
lfsr_mdir_t mdir;
lfsr_mtree_lookup(&lfs, mid, &mdir) => 0;
for (lfs_ssize_t rid = 0;
rid < (lfs_ssize_t)lfsr_mdir_weight(&mdir);
rid++) {
uint8_t buffer[4];
lfsr_mdir_get(&lfs, &mdir, rid, LFSR_TAG_INLINED,
buffer, 4) => 1;
assert(memcmp(buffer, &alphas[i % 26], 1) == 0);
i += 1;
}
}
assert(i == count);
lfsr_unmount(&lfs) => 0;
'''
## allocator tests
## note for these to work there are a number constraints on the device geometry
#if = 'BLOCK_CYCLES == -1'
+184 -184
View File
@@ -11,11 +11,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create an empty tree
@@ -42,11 +42,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a single-entry tree
@@ -81,11 +81,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a two-entry tree
@@ -127,11 +127,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a two-entry tree
@@ -174,11 +174,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a two-entry tree
@@ -228,11 +228,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a two-entry tree
@@ -285,11 +285,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a tree with N elements
@@ -337,11 +337,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a tree with N elements
@@ -402,11 +402,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a btree
@@ -486,11 +486,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a tree with N elements
@@ -568,11 +568,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a btree
@@ -707,11 +707,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a single-entry tree
@@ -748,11 +748,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a two-entry tree
@@ -799,11 +799,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a two-entry tree
@@ -861,11 +861,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a tree with N elements
@@ -944,11 +944,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a btree
@@ -1039,11 +1039,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a tree with N elements
@@ -1139,11 +1139,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a btree
@@ -1289,11 +1289,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a single-entry tree
@@ -1342,11 +1342,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a single-entry tree
@@ -1409,11 +1409,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a single-entry tree
@@ -1476,11 +1476,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a single-entry tree
@@ -1560,11 +1560,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a tree with N elements
@@ -1651,11 +1651,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a tree with N elements
@@ -1754,11 +1754,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a btree
@@ -1852,11 +1852,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a tree with N elements
@@ -1982,11 +1982,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a btree
@@ -2142,11 +2142,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a tree with N elements
@@ -2211,11 +2211,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a btree
@@ -2300,11 +2300,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a tree with N elements
@@ -2370,11 +2370,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a btree
@@ -2532,11 +2532,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a btree
@@ -2660,11 +2660,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a btree
@@ -2832,11 +2832,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a zero-entry tree
@@ -2863,11 +2863,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a single-entry tree
@@ -2910,11 +2910,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a two-entry tree
@@ -2968,11 +2968,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a two-entry tree
@@ -3037,11 +3037,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a two-entry tree
@@ -3107,11 +3107,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a tree with N elements
@@ -3184,11 +3184,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a btree
@@ -3292,11 +3292,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a tree with N elements
@@ -3371,11 +3371,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a btree
@@ -3532,11 +3532,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a btree
@@ -3717,11 +3717,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a btree
@@ -3939,11 +3939,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a tree with N elements
@@ -4070,11 +4070,11 @@ code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
// create free lookahead
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
lfs.free.off = 0;
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
memset(lfs.lookahead.buffer, 0, lfs.cfg->lookahead_size);
lfs.lookahead.start = 0;
lfs.lookahead.size = lfs_min(8*lfs.cfg->lookahead_size,
lfs.cfg->block_count);
lfs.free.i = 0;
lfs.lookahead.next = 0;
lfs_alloc_ack(&lfs);
// create a btree
+48
View File
@@ -20,6 +20,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
for (lfs_size_t i = 0; i < N; i++) {
lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS(
@@ -58,6 +59,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
for (lfs_size_t i = 0; i < N; i++) {
// force mroot to compact
@@ -99,6 +101,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
for (lfs_size_t i = 0; i < N; i++) {
lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS(
@@ -141,6 +144,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// prepare mroot with a large attr so the next entry can not fit
uint8_t buffer[SIZE];
@@ -212,6 +216,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create 2 large entries that needs to be uninlined and split
uint8_t buffer[SIZE];
@@ -282,6 +287,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create an uninlined mdir
uint8_t buffer[SIZE];
@@ -380,6 +386,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create entries
lfsr_mdir_t mdir;
@@ -473,6 +480,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// at least keep track of the number of entries we expect
lfs_size_t count = 0;
@@ -577,6 +585,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create an uninlined mdir
uint8_t buffer[SIZE];
@@ -643,6 +652,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create an uninlined mdir
uint8_t buffer[SIZE];
@@ -712,6 +722,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create an uninlined mdir
uint8_t buffer[SIZE];
@@ -768,6 +779,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create an mdir that needs to be split
uint8_t buffer[SIZE];
@@ -832,6 +844,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create an mdir that needs to be split
uint8_t buffer[SIZE];
@@ -896,6 +909,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create an mdir that needs to be split
uint8_t buffer[SIZE];
@@ -943,6 +957,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create an uninlined mdir
uint8_t buffer[SIZE];
@@ -1034,6 +1049,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create an uninlined mdir
uint8_t buffer[SIZE];
@@ -1125,6 +1141,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create an uninlined mdir
uint8_t buffer[SIZE];
@@ -1203,6 +1220,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create entries
lfsr_mdir_t mdir;
@@ -1298,6 +1316,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
for (lfs_size_t cycle = 0; cycle < CYCLES; cycle++) {
// create entries
@@ -1392,6 +1411,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// at least keep track of the number of entries we expect
lfs_size_t count = 0;
@@ -1521,6 +1541,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// prepare mroot with a large attr so the next entry can not fit
uint8_t buffer[SIZE];
@@ -1613,6 +1634,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create 2 large entries that needs to be uninlined and split
uint8_t buffer[SIZE];
@@ -1704,6 +1726,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create 2 large entries that needs to be uninlined and split
uint8_t buffer[SIZE];
@@ -1795,6 +1818,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// prepare mroot with an attr
uint8_t buffer[SIZE];
@@ -1851,6 +1875,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// prepare mroot with an attr
uint8_t buffer[SIZE];
@@ -1906,6 +1931,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// prepare mroot with an attr
uint8_t buffer[SIZE];
@@ -1970,6 +1996,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// prepare mroot with a large attr so the next entry can not fit
uint8_t buffer[SIZE];
@@ -2073,6 +2100,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create an uninlined mdir
uint8_t buffer[SIZE];
@@ -2183,6 +2211,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create an uninlined mdir
uint8_t buffer[SIZE];
@@ -2262,6 +2291,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// force mroot to compact once, so the second compact below will trigger
// a relocation
@@ -2347,6 +2377,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// force mroot to compact once, so the second compact below will trigger
// a relocation
@@ -2443,6 +2474,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// at least keep track of the number of entries we expect
lfs_size_t count = 0;
@@ -2580,6 +2612,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// setup our neighbors
lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS(
@@ -2664,6 +2697,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// setup our neighbors
lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS(
@@ -2705,6 +2739,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// setup our neighbors
lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS(
@@ -2774,6 +2809,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// setup our neighbors
lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS(
@@ -2843,6 +2879,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// setup our neighbors
lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS(
@@ -2936,6 +2973,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// setup our neighbors
lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS(
@@ -2997,6 +3035,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// setup our neighbors
lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS(
@@ -3085,6 +3124,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// insert a new entry, this should update our neighbors
lfsr_mdir_commit(&lfs, &lfs.mroot, &(lfs_ssize_t){-1}, LFSR_ATTRS(
@@ -3181,6 +3221,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// prepare mroot with a large attr so the next entry can not fit
uint8_t buffer[SIZE];
@@ -3310,6 +3351,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create 2 large entries that needs to be uninlined and split
uint8_t buffer[SIZE];
@@ -3441,6 +3483,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// prepare mroot with an attr
uint8_t buffer[SIZE];
@@ -3551,6 +3594,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// create entries
lfsr_mdir_t mdir;
@@ -3701,6 +3745,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// at least keep track of the number of entries we expect
lfs_size_t count = 0;
@@ -3860,6 +3905,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
uint8_t buffer[LFSR_MPTR_DSIZE];
lfs_ssize_t d = lfsr_mptr_todisk(&lfs, LFSR_MPTR_MROOTANCHOR, buffer);
@@ -3944,6 +3990,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// prepare mroot with an attr
uint8_t buffer[SIZE];
@@ -3998,6 +4045,7 @@ code = '''
lfs_t lfs;
lfsr_format(&lfs, cfg) => 0;
lfsr_mount(&lfs, cfg) => 0;
lfs_alloc_ack(&lfs);
// prepare mroot with an attr
uint8_t buffer[SIZE];