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
+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);