Fixed test failures caused by changes to open semantics

- Fixed fsync tests, which needed more lfsr_file_sync calls so multiple
  file handles can be opened correctly.

  Though this points out there's no way to open a rdonly file on an
  uncreated file until sync is called... But I guess you wouldn't be
  able to recieve broadcasts until sync anyways? at which point the file
  would be created?

- Update mtree tests based on the new remove behavior for regular files.

  Before this changed the mid to -1, now it points to the next mid with
  the zombie flag set. Upper layers use this to migrate mdirs to a
  scratch file if necessary.

- Removed the orphaned mdir test. We don't create orphaned mdirs
  anymore.

  Technically, orphaned mdirs are currently possible if we lose power in
  the middle of the mtree update, but this is a bug and should be fixed
  (previous revisions did not have this issue).
This commit is contained in:
Christopher Haster
2024-01-16 00:50:54 -06:00
parent 0c6db4c9a7
commit f6742eefb3
2 changed files with 12 additions and 108 deletions
+2 -108
View File
@@ -2355,7 +2355,7 @@ code = '''
assert(lfs.mroot.rbyd.weight == 2);
// assert that our neighbors were updated correctly
assert(left_neighbor.mdir.mid == -1);
assert(left_neighbor.mdir.mid == 1);
assert(right_neighbor.mdir.mid == 1);
assert(memcmp(&right_neighbor.mdir.rbyd, &lfs.mroot.rbyd,
sizeof(lfs.mroot.rbyd)) == 0);
@@ -2398,7 +2398,7 @@ code = '''
assert(left_neighbor.mdir.mid == 1);
assert(memcmp(&left_neighbor.mdir.rbyd, &lfs.mroot.rbyd,
sizeof(lfs.mroot.rbyd)) == 0);
assert(right_neighbor.mdir.mid == -1);
assert(right_neighbor.mdir.mid == 2);
lfsr_removeopened(&lfs, &left_neighbor);
lfsr_removeopened(&lfs, &right_neighbor);
@@ -3939,109 +3939,3 @@ code = '''
CFG->read(CFG, 1, 0, magic, lfs_max(16, READ_SIZE)) => 0;
assert(memcmp(&magic[8], "littlefs", 8) == 0);
'''
## Orphaned mdirs ##
# orphaned mdirs can happen if we lose power, test we can clean them up
[cases.test_mtree_orphans]
defines.N = 320
defines.ORPHANS = [1, 2, 3, 4]
defines.SEED = 42
in = 'lfs.c'
code = '''
const char *alphas = "abcdefghijklmnopqrstuvwxyz";
lfs_t lfs;
lfsr_format(&lfs, CFG) => 0;
lfsr_mount(&lfs, CFG) => 0;
lfs_alloc_ckpoint(&lfs);
// create entries
lfsr_mdir_t mdir;
lfsr_mtree_lookup(&lfs,
lfs_smax32(
lfsr_mtree_weight(&lfs) - lfsr_mweight(&lfs),
0),
&mdir) => 0;
mdir.mid += 1;
for (lfs_size_t i = 0; i < N; i++) {
lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS(
LFSR_ATTR(mdir.mid, REG, +1,
BUF(&alphas[i % 26], 1)))) => 0;
uint8_t buffer[4];
lfsr_mdir_get(&lfs, &mdir, mdir.mid, LFSR_TAG_REG,
buffer, 4) => 1;
assert(memcmp(buffer, &alphas[i % 26], 1) == 0);
mdir.mid += 1;
}
lfsr_mid_t old_weight = lfsr_mtree_weight(&lfs);
// this test only works with a full mtree
LFS_ASSERT(lfsr_mtree_isbtree(&lfs));
// bypass the mdir logic and create some orphans
uint32_t prng = SEED;
for (lfs_size_t i = 0; i < ORPHANS; i++) {
// note we should never have orphan.mid=0
lfsr_bid_t bid_ = ((TEST_PRNG(&prng)
% (lfsr_mtree_weight(&lfs)/lfsr_mweight(&lfs))) + 1)
* lfsr_mweight(&lfs);
// manually allocate/commit an empty mdir, otherwise
// lfsr_mdir_commit automatically cleans up empty mdirs
lfsr_mptr_t mptr;
for (lfs_size_t j = 0; j < 2; j++) {
lfsr_rbyd_t rbyd;
lfsr_rbyd_alloc(&lfs, &rbyd) => 0;
lfsr_rbyd_commit(&lfs, &rbyd, LFSR_ATTRS(
LFSR_ATTR(0, REG, +1, BUF("a", 1)),
LFSR_ATTR(0, RM, -1, NULL()))) => 0;
mptr.blocks[j] = rbyd.blocks[0];
}
// commit orphan to tree
uint8_t mptr_buf[LFSR_MPTR_DSIZE];
lfsr_mtree_commit(&lfs, LFSR_ATTRS(
LFSR_ATTR(bid_,
MDIR, +lfsr_mweight(&lfs),
FROMMPTR(&mptr, mptr_buf)))) => 0;
}
LFS_ASSERT(lfsr_mtree_weight(&lfs) > old_weight);
// trigger lfsr_fs_fixorphans
lfs.hasorphans = true;
lfsr_fs_preparemutation(&lfs) => 0;
// this should have removed all of our orphans
LFS_ASSERT(lfsr_mtree_weight(&lfs) == old_weight);
// try looking up each entry
lfs_size_t i = 0;
for (lfs_ssize_t mid = 0;
mid < lfs_smax32(
lfsr_mtree_weight(&lfs),
lfsr_mweight(&lfs));
mid += lfsr_mweight(&lfs)) {
lfsr_mdir_t mdir;
lfsr_mtree_lookup(&lfs, mid, &mdir) => 0;
for (; lfsr_mdir_rid(&lfs, &mdir) < mdir.rbyd.weight;
mdir.mid += 1) {
// skip the root bookmark
if (mdir.mid == 0) {
continue;
}
uint8_t buffer[4];
lfsr_mdir_get(&lfs, &mdir, mdir.mid, LFSR_TAG_REG,
buffer, 4) => 1;
assert(memcmp(buffer, &alphas[i % 26], 1) == 0);
i += 1;
}
}
assert(i == N);
lfsr_unmount(&lfs) => 0;
'''