Added some more mtree tests, fixed mroot extension bug

- Finally figured out how to test multiple mroot extensions without an
  allocator, though hopefully forcing PROG_SIZE doesn't break test
  framework things at some point...

- Added tests that magic string is always in the same place. This isn't
  strictly required for littlefs to work, but is a nice feature to have.

Of course, the new tests found a bug, but it was in a surprisingly
place. Accidentally allowed the revision count to be uninitialized when
compacting the mroot. At least there's a test that covers this now.
This commit is contained in:
Christopher Haster
2023-06-20 01:18:10 -05:00
parent 0690a86f1d
commit 854e1e68f0
2 changed files with 216 additions and 29 deletions
+28 -29
View File
@@ -4846,41 +4846,40 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir,
// - mid = manchor => never alloc (mroot anchor)
// - mid = wl => only alloc if mdir is tired (wear-leveling)
// - otherwise => always alloc, use this mid (new mdir)
// first thing we need to do is read our current revision count
uint32_t rev;
if (mid != LFSR_MID_MANCHOR) {
// first thing we need to do is read our current revision count
int err = lfsr_bd_read(lfs, source->rbyd.block, 0, sizeof(uint32_t),
int err = lfsr_bd_read(lfs, source->rbyd.block, 0, sizeof(uint32_t),
&rev, sizeof(uint32_t));
if (err && err != LFS_ERR_CORRUPT) {
return err;
}
// note we allow corrupt errors here, as long as they are consistent
rev = (err != LFS_ERR_CORRUPT ? lfs_fromle32_(&rev) : 0);
// decide if we need to relocate
if (mid != LFSR_MID_MANCHOR && (mid != LFSR_MID_WL || (
lfs->cfg->block_cycles > 0
// TODO rev things
&& (rev + 1) % lfs->cfg->block_cycles == 0))) {
// allocate a new mdir for relocation
err = lfsr_mdir_alloc(lfs, mdir,
(mid != LFSR_MID_WL ? mid : mdir->mid));
if (err) {
return err;
}
// read the new revision count
//
// we use whatever is on-disk to avoid needing to rewrite the
// redund block
err = lfsr_bd_read(lfs, mdir->rbyd.block, 0, sizeof(uint32_t),
&rev, sizeof(uint32_t));
if (err && err != LFS_ERR_CORRUPT) {
return err;
}
// note we allow corrupt errors here, as long as they are consistent
rev = (err != LFS_ERR_CORRUPT ? lfs_fromle32_(&rev) : 0);
// decide if we need to relocate
if (mid != LFSR_MID_WL || (
lfs->cfg->block_cycles > 0
// TODO rev things
&& (rev + 1) % lfs->cfg->block_cycles == 0)) {
// allocate a new mdir for relocation
err = lfsr_mdir_alloc(lfs, mdir,
(mid != LFSR_MID_WL ? mid : mdir->mid));
if (err) {
return err;
}
// read the new revision count
//
// we use whatever is on-disk to avoid needing to rewrite the
// redund block
err = lfsr_bd_read(lfs, mdir->rbyd.block, 0, sizeof(uint32_t),
&rev, sizeof(uint32_t));
if (err && err != LFS_ERR_CORRUPT) {
return err;
}
// note we allow corrupt errors here, as long as they are consistent
rev = (err != LFS_ERR_CORRUPT ? lfs_fromle32_(&rev) : 0);
}
}
// swap our rbyds
@@ -4892,7 +4891,7 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir,
mdir->rbyd.crc = 0;
// erase, preparing for compact
int err = lfsr_bd_erase(lfs, mdir->rbyd.block);
err = lfsr_bd_erase(lfs, mdir->rbyd.block);
if (err) {
return err;
}