preerase: Added test_mount_t_preerase, fixed several more bugs

- Fixed lfs3_alloc_cansyncgbmap ignoring known window changes.

  Being able to just call lfs3_btree_cmp(b, b_p) would be nice, but this
  ignores known window changes!

  Fixed by comparing the on-disk encoding, which is heavy-handed, but
  probably the safest approach.

  lfs3_alloc_cansyncgbmap will probably never be on the stack hot-path,
  and the added code is roughly one function call. The main cost is
  CPU-cycles, but fortunately(?) that's not something we really care
  about?

- Fixed lfs3_allocclaim accidentally returning lfs3_mdir_commit's return
  value instead of the allocated block!

  Probably caused by a copy-paste, resulted in lfs3_allocclaim returning
  block 0, which is really not good!

- Fixed assert typo in lfs3_trv_open where we assert REVPERTURB in flags
  instead of lfs3->flags.

Code changes:

                    code          stack          ctx
  before:          35260           2136          660
  after:           35260 (+0.0%)   2136 (+0.0%)  660 (+0.0%)

                    code          stack          ctx
  gbmap before:    38560           2144          776
  gbmap after:     38616 (+0.1%)   2144 (+0.0%)  776 (+0.0%)

                    code          stack          ctx
  preerase before: 39168           2168          796
  preerase after:  39232 (+0.2%)   2168 (+0.0%)  796 (+0.0%)
This commit is contained in:
Christopher Haster
2026-01-03 01:18:54 -06:00
parent 35c09db971
commit 9bd44aec12
4 changed files with 227 additions and 20 deletions
+15 -3
View File
@@ -10868,7 +10868,15 @@ static inline bool lfs3_alloc_canpreerase(const lfs3_t *lfs3) {
// is gbmap out-of-sync with disk?
#if !defined(LFS3_RDONLY) && defined(LFS3_GBMAP)
static inline bool lfs3_alloc_cansyncgbmap(const lfs3_t *lfs3) {
return lfs3_btree_cmp(&lfs3->gbmap.b, &lfs3->gbmap.b_p) != 0;
// do we even have a gbmap?
if (!lfs3_f_isgbmap(lfs3->flags)) {
return false;
}
// just compare the on-disk encoding
uint8_t gbmap_[LFS3_GBMAP_DSIZE];
lfs3_data_fromgbmap(&lfs3->gbmap, gbmap_);
return memcmp(gbmap_, lfs3->gbmap_p, LFS3_GBMAP_DSIZE) != 0;
}
#endif
@@ -11311,7 +11319,10 @@ static lfs3_sblock_t lfs3_allocclaim(lfs3_t *lfs3, lfs3_mdir_t *mdir,
if (lfs3_ecksum_isecksum(&ecksum_)) {
LFS3_ASSERT(lfs3_alloc_cansyncgbmap(lfs3));
// lfs3_mdir_commit implicitly commits any pending gbmap state
return lfs3_mdir_commit(lfs3, mdir, LFS3_RATTRS(LFS3_RATTR_NULL));
int err = lfs3_mdir_commit(lfs3, mdir, LFS3_RATTRS(LFS3_RATTR_NULL));
if (err) {
return err;
}
}
#endif
@@ -17091,7 +17102,8 @@ int lfs3_trv_open(lfs3_t *lfs3, lfs3_trv_t *trv, uint32_t flags) {
// we can't use preerased blocks without revperturb, so this is
// likely a mistake
#if !defined(LFS3_RDONLY) && defined(LFS3_PREERASE)
LFS3_ASSERT(lfs3_m_isrevperturb(flags) || !lfs3_t_ispreerase(flags));
LFS3_ASSERT(lfs3_m_isrevperturb(lfs3->flags)
|| !lfs3_t_ispreerase(flags));
#endif
// setup traversal state