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:
+2
-108
@@ -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;
|
||||
'''
|
||||
|
||||
Reference in New Issue
Block a user