bmap: Fixed up low-hanging fruit, tests and things

- Consistent grm_op -> alloc_ckpoint -> mdir_commit order
- Drop some low priority TODOs
- Got test_alloc at least passing existing tests
- Got test_gc passing
- Got test_mount passing
- test_relocations was already passing, lol

No code changes:

                code          stack          ctx
  before:      36912           2368          684
  after:       36912 (+0.0%)   2368 (+0.0%)  684 (+0.0%)

                code          stack          ctx
  bmap before: 38456           2400          812
  bmap after:  38456 (+0.0%)   2400 (+0.0%)  812 (+0.0%)
This commit is contained in:
Christopher Haster
2025-07-29 15:38:42 -05:00
parent 047fb83b62
commit 41be512272
6 changed files with 51 additions and 34 deletions
+6 -6
View File
@@ -10812,6 +10812,7 @@ static int lfs3_alloc_rebuildbmap(lfs3_t *lfs3);
#if !defined(LFS3_RDONLY) #if !defined(LFS3_RDONLY)
static inline void lfs3_alloc_ckpoint(lfs3_t *lfs3) { static inline void lfs3_alloc_ckpoint(lfs3_t *lfs3) {
#ifndef LFS3_2BONLY #ifndef LFS3_2BONLY
// checkpoint the allocator
lfs3->lookahead.ckpoint = lfs3->block_count; lfs3->lookahead.ckpoint = lfs3->block_count;
#ifdef LFS3_BMAP #ifdef LFS3_BMAP
// do we need to rebuild the bmap? // do we need to rebuild the bmap?
@@ -10821,6 +10822,8 @@ static inline void lfs3_alloc_ckpoint(lfs3_t *lfs3) {
int err = lfs3_alloc_rebuildbmap(lfs3); int err = lfs3_alloc_rebuildbmap(lfs3);
// TODO lfs3_alloc_ckpoint should propagate errors // TODO lfs3_alloc_ckpoint should propagate errors
LFS3_ASSERT(!err); LFS3_ASSERT(!err);
// // checkpoint the allocator again after rebuilding the bmap
// lfs3->lookahead.ckpoint = lfs3->block_count;
} }
#endif #endif
#else #else
@@ -11497,13 +11500,10 @@ int lfs3_mkdir(lfs3_t *lfs3, const char *path) {
? tag_ >= 0 ? tag_ >= 0
: tag_ == LFS3_ERR_NOENT); : 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 // commit our new directory into our parent, zeroing the grm in the
// process // process
lfs3_alloc_ckpoint(lfs3);
lfs3_grm_pop(lfs3); lfs3_grm_pop(lfs3);
lfs3_alloc_ckpoint(lfs3);
err = lfs3_mdir_commit(lfs3, &mdir, LFS3_RATTRS( err = lfs3_mdir_commit(lfs3, &mdir, LFS3_RATTRS(
LFS3_RATTR_NAME( LFS3_RATTR_NAME(
LFS3_TAG_MASK12 | LFS3_TAG_DIR, LFS3_TAG_MASK12 | LFS3_TAG_DIR,
@@ -16560,10 +16560,10 @@ static int lfs3_fs_fixgrm(lfs3_t *lfs3) {
// we need to revert manually on error // we need to revert manually on error
lfs3_grm_t grm_p = lfs3->grm; lfs3_grm_t grm_p = lfs3->grm;
// checkpoint the allocator
lfs3_alloc_ckpoint(lfs3);
// mark grm as taken care of // mark grm as taken care of
lfs3_grm_pop(lfs3); lfs3_grm_pop(lfs3);
// checkpoint the allocator
lfs3_alloc_ckpoint(lfs3);
// remove the rid while atomically updating our grm // remove the rid while atomically updating our grm
err = lfs3_mdir_commit(lfs3, &mdir, LFS3_RATTRS( err = lfs3_mdir_commit(lfs3, &mdir, LFS3_RATTRS(
LFS3_RATTR(LFS3_TAG_RM, -1))); LFS3_RATTR(LFS3_TAG_RM, -1)));
+18 -5
View File
@@ -9,8 +9,11 @@
# #
after = ['test_mtree', 'test_bmap', 'test_dirs', 'test_files'] after = ['test_mtree', 'test_bmap', 'test_dirs', 'test_files']
# TODO bmap workaround? # TODO should we rename these to test_lookahead?
ifndef = 'LFS3_BMAP' # TODO or extend to test the bmap as well?
#
# these are really tuned to test the lookahead allocator
#ifndef = 'LFS3_BMAP'
# test that we can alloc # test that we can alloc
[cases.test_alloc_alloc] [cases.test_alloc_alloc]
@@ -23,6 +26,7 @@ defines.COUNT = [
'2', '2',
] ]
defines.ERASE = [false, true] defines.ERASE = [false, true]
if = 'COUNT >= LFS3_IFDEF_BMAP(3, 2)'
in = 'lfs3.c' in = 'lfs3.c'
code = ''' code = '''
// test various block counts // test various block counts
@@ -49,9 +53,11 @@ code = '''
} }
// excluding our mroot, we should have allocated exactly // excluding our mroot, we should have allocated exactly
// block_count-2 blocks // block_count-2 blocks (this gets more complicated with a bmap)
printf("alloced %d/%d blocks\n", alloced, (lfs3_block_t)COUNT); printf("alloced %d/%d blocks\n", alloced, (lfs3_block_t)COUNT);
#ifndef LFS3_BMAP
assert(alloced == COUNT-2); assert(alloced == COUNT-2);
#endif
lfs3_unmount(&lfs3) => 0; lfs3_unmount(&lfs3) => 0;
''' '''
@@ -67,6 +73,7 @@ defines.COUNT = [
'2', '2',
] ]
defines.ERASE = [false, true] defines.ERASE = [false, true]
if = 'COUNT >= LFS3_IFDEF_BMAP(3, 2)'
in = 'lfs3.c' in = 'lfs3.c'
code = ''' code = '''
// test various block counts // test various block counts
@@ -93,9 +100,11 @@ code = '''
} }
// excluding our mroot, we should have allocated exactly // excluding our mroot, we should have allocated exactly
// block_count-2 blocks // block_count-2 blocks (this gets more complicated with a bmap)
printf("alloced %d/%d blocks\n", alloced, (lfs3_block_t)COUNT); printf("alloced %d/%d blocks\n", alloced, (lfs3_block_t)COUNT);
#ifndef LFS3_BMAP
assert(alloced == COUNT-2); assert(alloced == COUNT-2);
#endif
// ack again, effectively releasing all the previously alloced blocks // ack again, effectively releasing all the previously alloced blocks
lfs3_alloc_ckpoint(&lfs3); lfs3_alloc_ckpoint(&lfs3);
@@ -114,9 +123,11 @@ code = '''
} }
// excluding our mroot, we should have allocated exactly // excluding our mroot, we should have allocated exactly
// block_count-2 blocks // block_count-2 blocks (this gets more complicated with a bmap)
printf("alloced %d/%d blocks\n", alloced, (lfs3_block_t)COUNT); printf("alloced %d/%d blocks\n", alloced, (lfs3_block_t)COUNT);
#ifndef LFS3_BMAP
assert(alloced == COUNT-2); assert(alloced == COUNT-2);
#endif
lfs3_unmount(&lfs3) => 0; lfs3_unmount(&lfs3) => 0;
''' '''
@@ -648,6 +659,7 @@ defines.COUNT = [
'5', '5',
'2', '2',
] ]
if = 'COUNT >= LFS3_IFDEF_BMAP(3, 2)'
code = ''' code = '''
// test various block counts // test various block counts
struct lfs3_cfg cfg = *CFG; struct lfs3_cfg cfg = *CFG;
@@ -730,6 +742,7 @@ defines.SIZE = [
'2*BLOCK_SIZE', '2*BLOCK_SIZE',
'8*BLOCK_SIZE', '8*BLOCK_SIZE',
] ]
if = 'COUNT >= LFS3_IFDEF_BMAP(3, 2)'
code = ''' code = '''
// test various block counts // test various block counts
struct lfs3_cfg cfg = *CFG; struct lfs3_cfg cfg = *CFG;
+1 -1
View File
@@ -1,7 +1,7 @@
# Test the mid-level B-trees # Test the mid-level B-trees
after = 'test_rbyd' after = 'test_rbyd'
# TODO bmap workaround? # don't bother testing with more complicated block allocators
ifndef = 'LFS3_BMAP' ifndef = 'LFS3_BMAP'
# maximize lookahead buffer, we don't actually gc so we only get one pass # maximize lookahead buffer, we don't actually gc so we only get one pass
+12 -9
View File
@@ -4,9 +4,6 @@
# GC-API specific things here # GC-API specific things here
after = ['test_trvs'] after = ['test_trvs']
# TODO bmap workaround?
ifndef = 'LFS3_BMAP'
# test that lookahead can make progress in isolation # test that lookahead can make progress in isolation
[cases.test_gc_lookahead_progress] [cases.test_gc_lookahead_progress]
defines.CKMETA = [false, true] defines.CKMETA = [false, true]
@@ -1461,7 +1458,8 @@ code = '''
| LFS3_I_LOOKAHEAD | LFS3_I_LOOKAHEAD
| LFS3_I_COMPACT | LFS3_I_COMPACT
| LFS3_I_CKMETA | LFS3_I_CKMETA
| LFS3_I_CKDATA)); | LFS3_I_CKDATA
| LFS3_IFDEF_BMAP(LFS3_I_BMAPCACHE, 0)));
// run gc // run gc
if (AFTER == 0) { if (AFTER == 0) {
@@ -1576,7 +1574,8 @@ code = '''
| ((!COMPACT) ? LFS3_I_COMPACT : 0) | ((!COMPACT) ? LFS3_I_COMPACT : 0)
// note ckdata implies ckmeta // note ckdata implies ckmeta
| ((!CKMETA && !CKDATA) ? LFS3_I_CKMETA : 0) | ((!CKMETA && !CKDATA) ? LFS3_I_CKMETA : 0)
| ((!CKDATA) ? LFS3_I_CKDATA : 0))); | ((!CKDATA) ? LFS3_I_CKDATA : 0)
| LFS3_IFDEF_BMAP(LFS3_I_BMAPCACHE, 0)));
lfs3_unmount(&lfs3) => 0; lfs3_unmount(&lfs3) => 0;
''' '''
@@ -1650,7 +1649,8 @@ code = '''
| LFS3_I_LOOKAHEAD | LFS3_I_LOOKAHEAD
| LFS3_I_COMPACT | LFS3_I_COMPACT
| LFS3_I_CKMETA | LFS3_I_CKMETA
| LFS3_I_CKDATA)); | LFS3_I_CKDATA
| LFS3_IFDEF_BMAP(LFS3_I_BMAPCACHE, 0)));
// run gc // run gc
if (AFTER == 0) { if (AFTER == 0) {
@@ -1765,7 +1765,8 @@ code = '''
| ((!COMPACT) ? LFS3_I_COMPACT : 0) | ((!COMPACT) ? LFS3_I_COMPACT : 0)
// note ckdata implies ckmeta // note ckdata implies ckmeta
| ((!CKMETA && !CKDATA) ? LFS3_I_CKMETA : 0) | ((!CKMETA && !CKDATA) ? LFS3_I_CKMETA : 0)
| ((!CKDATA) ? LFS3_I_CKDATA : 0))); | ((!CKDATA) ? LFS3_I_CKDATA : 0)
| LFS3_IFDEF_BMAP(LFS3_I_BMAPCACHE, 0)));
// test that we can reset flags with lfs3_fs_unck // test that we can reset flags with lfs3_fs_unck
lfs3_fs_unck(&lfs3, GC_FLAGS) => 0; lfs3_fs_unck(&lfs3, GC_FLAGS) => 0;
@@ -1779,7 +1780,8 @@ code = '''
// note ckdata implies ckmeta, but uncking ckdata does // note ckdata implies ckmeta, but uncking ckdata does
// _not_ imply uncking ckmeta // _not_ imply uncking ckmeta
| ((!(CKDATA && !CKMETA)) ? LFS3_I_CKMETA : 0) | ((!(CKDATA && !CKMETA)) ? LFS3_I_CKMETA : 0)
| LFS3_I_CKDATA)); | LFS3_I_CKDATA
| LFS3_IFDEF_BMAP(LFS3_I_BMAPCACHE, 0)));
// run gc // run gc
if (AFTER == 0) { if (AFTER == 0) {
@@ -1894,7 +1896,8 @@ code = '''
| ((!COMPACT) ? LFS3_I_COMPACT : 0) | ((!COMPACT) ? LFS3_I_COMPACT : 0)
// note ckdata implies ckmeta // note ckdata implies ckmeta
| ((!CKMETA && !CKDATA) ? LFS3_I_CKMETA : 0) | ((!CKMETA && !CKDATA) ? LFS3_I_CKMETA : 0)
| ((!CKDATA) ? LFS3_I_CKDATA : 0))); | ((!CKDATA) ? LFS3_I_CKDATA : 0)
| LFS3_IFDEF_BMAP(LFS3_I_BMAPCACHE, 0)));
lfs3_unmount(&lfs3) => 0; lfs3_unmount(&lfs3) => 0;
''' '''
+14 -10
View File
@@ -1,9 +1,6 @@
# Advanced mount tests # Advanced mount tests
after = ['test_mtree', 'test_trvs'] after = ['test_mtree', 'test_trvs']
# TODO bmap workaround?
ifndef = 'LFS3_BMAP'
# test we can mount # test we can mount
[cases.test_mount_simple] [cases.test_mount_simple]
@@ -89,7 +86,8 @@ code = '''
| ((!COMPACT) ? LFS3_I_COMPACT : 0) | ((!COMPACT) ? LFS3_I_COMPACT : 0)
// note ckdata implies ckmeta // note ckdata implies ckmeta
| ((!CKMETA && !CKDATA) ? LFS3_I_CKMETA : 0) | ((!CKMETA && !CKDATA) ? LFS3_I_CKMETA : 0)
| ((!CKDATA) ? LFS3_I_CKDATA : 0))); | ((!CKDATA) ? LFS3_I_CKDATA : 0)
| LFS3_IFDEF_BMAP(LFS3_I_BMAPCACHE, 0)));
lfs3_unmount(&lfs3) => 0; lfs3_unmount(&lfs3) => 0;
''' '''
@@ -156,7 +154,8 @@ code = '''
| LFS3_I_LOOKAHEAD | LFS3_I_LOOKAHEAD
| LFS3_I_COMPACT | LFS3_I_COMPACT
| LFS3_I_CKMETA | LFS3_I_CKMETA
| LFS3_I_CKDATA)); | LFS3_I_CKDATA
| LFS3_IFDEF_BMAP(LFS3_I_BMAPCACHE, 0)));
lfs3_unmount(&lfs3) => 0; lfs3_unmount(&lfs3) => 0;
// with LFS3_M_LOOKAHEAD, mount performs a lookahead scan // with LFS3_M_LOOKAHEAD, mount performs a lookahead scan
@@ -172,7 +171,8 @@ code = '''
| LFS3_I_COMPACT | LFS3_I_COMPACT
// note ckdata implies ckmeta // note ckdata implies ckmeta
| ((!CKMETA && !CKDATA) ? LFS3_I_CKMETA : 0) | ((!CKMETA && !CKDATA) ? LFS3_I_CKMETA : 0)
| ((!CKDATA) ? LFS3_I_CKDATA : 0))); | ((!CKDATA) ? LFS3_I_CKDATA : 0)
| LFS3_IFDEF_BMAP(LFS3_I_BMAPCACHE, 0)));
lfs3_unmount(&lfs3) => 0; lfs3_unmount(&lfs3) => 0;
''' '''
@@ -227,7 +227,8 @@ code = '''
| LFS3_I_LOOKAHEAD | LFS3_I_LOOKAHEAD
| LFS3_I_COMPACT | LFS3_I_COMPACT
| LFS3_I_CKMETA | LFS3_I_CKMETA
| LFS3_I_CKDATA)); | LFS3_I_CKDATA
| LFS3_IFDEF_BMAP(LFS3_I_BMAPCACHE, 0)));
lfs3_unmount(&lfs3) => 0; lfs3_unmount(&lfs3) => 0;
// with LFS3_M_COMPACT, mount compact any uncompacted blocks // with LFS3_M_COMPACT, mount compact any uncompacted blocks
@@ -244,7 +245,8 @@ code = '''
| ((!LOOKAHEAD) ? LFS3_I_LOOKAHEAD : 0) | ((!LOOKAHEAD) ? LFS3_I_LOOKAHEAD : 0)
// note ckdata implies ckmeta // note ckdata implies ckmeta
| ((!CKMETA && !CKDATA) ? LFS3_I_CKMETA : 0) | ((!CKMETA && !CKDATA) ? LFS3_I_CKMETA : 0)
| ((!CKDATA) ? LFS3_I_CKDATA : 0))); | ((!CKDATA) ? LFS3_I_CKDATA : 0)
| LFS3_IFDEF_BMAP(LFS3_I_BMAPCACHE, 0)));
// mdir should have been compacted // mdir should have been compacted
lfs3_file_open(&lfs3, &file, "jellyfish", LFS3_O_RDONLY) => 0; lfs3_file_open(&lfs3, &file, "jellyfish", LFS3_O_RDONLY) => 0;
@@ -329,7 +331,8 @@ code = '''
| LFS3_I_LOOKAHEAD | LFS3_I_LOOKAHEAD
| LFS3_I_COMPACT | LFS3_I_COMPACT
| LFS3_I_CKMETA | LFS3_I_CKMETA
| LFS3_I_CKDATA)); | LFS3_I_CKDATA
| LFS3_IFDEF_BMAP(LFS3_I_BMAPCACHE, 0)));
lfs3_unmount(&lfs3) => 0; lfs3_unmount(&lfs3) => 0;
// with LFS3_M_MKCONSISTENT, mount cleans up orphans eagerly // with LFS3_M_MKCONSISTENT, mount cleans up orphans eagerly
@@ -347,7 +350,8 @@ code = '''
| ((!COMPACT) ? LFS3_I_COMPACT : 0) | ((!COMPACT) ? LFS3_I_COMPACT : 0)
// note ckdata implies ckmeta // note ckdata implies ckmeta
| ((!CKMETA && !CKDATA) ? LFS3_I_CKMETA : 0) | ((!CKMETA && !CKDATA) ? LFS3_I_CKMETA : 0)
| ((!CKDATA) ? LFS3_I_CKDATA : 0))); | ((!CKDATA) ? LFS3_I_CKDATA : 0)
| LFS3_IFDEF_BMAP(LFS3_I_BMAPCACHE, 0)));
// check we can still read the files // check we can still read the files
lfs3_file_open(&lfs3, &file, "cuttlefish", LFS3_O_RDONLY) => 0; lfs3_file_open(&lfs3, &file, "cuttlefish", LFS3_O_RDONLY) => 0;
-3
View File
@@ -7,9 +7,6 @@ after = [
'test_powerloss', 'test_powerloss',
] ]
# TODO bmap workaround?
ifndef = 'LFS3_BMAP'
# Note that most of the delicate relocation operations are already tested # Note that most of the delicate relocation operations are already tested
# in test_mtree. This mostly just covers high-level operations with # in test_mtree. This mostly just covers high-level operations with
# relatively aggressive wear-leveling. # relatively aggressive wear-leveling.