gc: Renamed lfsr_gc -> lfsr_fs_gc, keep lfsr_fs_unck in non-gc
- lfsr_gc -> lfsr_fs_gc
- lfsr_gc_unck -> lfsr_fs_unck
lfsr_fs_unck is surprisingly still useful in non-gc builds, since we
still have ckmeta/ckdata state. These flags can still be queried with
lfsr_fs_stat and cleared with lfsr_fs_ckmeta/ckdata/lfsr_traversal_t, so
it seems useful to keep this function around.
It's also a relatively cheap function.
Though this does mean it deserves a rename. Dropping the gc prefix
hopefully makes it clearer this function is not entirely gc-specific.
And since we no longer have lfsr_gc_setflags/setsteps, it makes sense to
rename lfsr_gc back to lfsr_fs_gc, to be consistent with the other
filesystem-wide utilities.
Code changes, apparently lfsr_fs_unck costs 12 bytes:
code stack ctx
default before: 37792 2608 620
default after: 37804 (+0.0%) 2608 (+0.0%) 620 (+0.0%)
gc before: 37938 2608 768
gc after: 37940 (+0.0%) 2608 (+0.0%) 768 (+0.0%)
This commit is contained in:
@@ -13952,7 +13952,7 @@ static int lfsr_mountinited(lfs_t *lfs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// needed in lfsr_mount
|
// needed in lfsr_mount
|
||||||
static int lfsr_fs_gc(lfs_t *lfs, lfsr_traversal_t *t,
|
static int lfsr_fs_gc_(lfs_t *lfs, lfsr_traversal_t *t,
|
||||||
uint32_t flags, lfs_soff_t steps);
|
uint32_t flags, lfs_soff_t steps);
|
||||||
|
|
||||||
int lfsr_mount(lfs_t *lfs, uint32_t flags,
|
int lfsr_mount(lfs_t *lfs, uint32_t flags,
|
||||||
@@ -14010,7 +14010,7 @@ int lfsr_mount(lfs_t *lfs, uint32_t flags,
|
|||||||
| LFS_M_CKMETA
|
| LFS_M_CKMETA
|
||||||
| LFS_M_CKDATA)) {
|
| LFS_M_CKDATA)) {
|
||||||
lfsr_traversal_t t;
|
lfsr_traversal_t t;
|
||||||
err = lfsr_fs_gc(lfs, &t,
|
err = lfsr_fs_gc_(lfs, &t,
|
||||||
flags & (
|
flags & (
|
||||||
LFS_M_MTREEONLY
|
LFS_M_MTREEONLY
|
||||||
| LFS_M_MKCONSISTENT
|
| LFS_M_MKCONSISTENT
|
||||||
@@ -14189,7 +14189,7 @@ int lfsr_format(lfs_t *lfs, uint32_t flags,
|
|||||||
| LFS_F_CKMETA
|
| LFS_F_CKMETA
|
||||||
| LFS_F_CKDATA)) {
|
| LFS_F_CKDATA)) {
|
||||||
lfsr_traversal_t t;
|
lfsr_traversal_t t;
|
||||||
err = lfsr_fs_gc(lfs, &t,
|
err = lfsr_fs_gc_(lfs, &t,
|
||||||
flags & (
|
flags & (
|
||||||
LFS_F_MTREEONLY
|
LFS_F_MTREEONLY
|
||||||
| LFS_F_COMPACT
|
| LFS_F_COMPACT
|
||||||
@@ -14449,7 +14449,7 @@ int lfsr_fs_ckdata(lfs_t *lfs) {
|
|||||||
//
|
//
|
||||||
// runs the traversal until all work is completed, which may take
|
// runs the traversal until all work is completed, which may take
|
||||||
// multiple passes
|
// multiple passes
|
||||||
static int lfsr_fs_gc(lfs_t *lfs, lfsr_traversal_t *t,
|
static int lfsr_fs_gc_(lfs_t *lfs, lfsr_traversal_t *t,
|
||||||
uint32_t flags, lfs_soff_t steps) {
|
uint32_t flags, lfs_soff_t steps) {
|
||||||
// unknown gc flags?
|
// unknown gc flags?
|
||||||
//
|
//
|
||||||
@@ -14555,6 +14555,40 @@ static int lfsr_fs_gc(lfs_t *lfs, lfsr_traversal_t *t,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LFS_GC
|
||||||
|
// incremental filesystem gc
|
||||||
|
//
|
||||||
|
// perform any pending janitorial work
|
||||||
|
int lfsr_fs_gc(lfs_t *lfs) {
|
||||||
|
return lfsr_fs_gc_(lfs, &lfs->gc.t,
|
||||||
|
lfs->gc.flags, lfs->gc.steps);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// unperform janitorial work
|
||||||
|
int lfsr_fs_unck(lfs_t *lfs, uint32_t flags) {
|
||||||
|
// unknown flags?
|
||||||
|
LFS_ASSERT((flags & ~(
|
||||||
|
LFS_I_INCONSISTENT
|
||||||
|
| LFS_I_CANLOOKAHEAD
|
||||||
|
| LFS_I_UNCOMPACTED
|
||||||
|
| LFS_I_CANCKMETA
|
||||||
|
| LFS_I_CANCKDATA)) == 0);
|
||||||
|
|
||||||
|
// reset the requested flags
|
||||||
|
lfs->flags |= flags;
|
||||||
|
|
||||||
|
#ifdef LFS_GC
|
||||||
|
// and clear from any ongoing traversals
|
||||||
|
//
|
||||||
|
// lfsr_fs_gc will terminate early if it discovers it can no longer
|
||||||
|
// make progress
|
||||||
|
lfs->gc.t.o.o.flags &= ~flags;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// attempt to grow the filesystem
|
// attempt to grow the filesystem
|
||||||
int lfsr_fs_grow(lfs_t *lfs, lfs_size_t block_count_) {
|
int lfsr_fs_grow(lfs_t *lfs, lfs_size_t block_count_) {
|
||||||
@@ -14786,42 +14820,6 @@ int lfsr_traversal_rewind(lfs_t *lfs, lfsr_traversal_t *t) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Incremental gc operations ///
|
|
||||||
|
|
||||||
#ifdef LFS_GC
|
|
||||||
// perform any pending janitorial work
|
|
||||||
int lfsr_gc(lfs_t *lfs) {
|
|
||||||
return lfsr_fs_gc(lfs, &lfs->gc.t,
|
|
||||||
lfs->gc.flags, lfs->gc.steps);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef LFS_GC
|
|
||||||
// unperform janitorial work
|
|
||||||
int lfsr_gc_unck(lfs_t *lfs, uint32_t flags) {
|
|
||||||
// unknown flags?
|
|
||||||
LFS_ASSERT((flags & ~(
|
|
||||||
LFS_I_INCONSISTENT
|
|
||||||
| LFS_I_CANLOOKAHEAD
|
|
||||||
| LFS_I_UNCOMPACTED
|
|
||||||
| LFS_I_CANCKMETA
|
|
||||||
| LFS_I_CANCKDATA)) == 0);
|
|
||||||
|
|
||||||
// reset the requested flags
|
|
||||||
lfs->flags |= flags;
|
|
||||||
|
|
||||||
// and clear from any ongoing traversals
|
|
||||||
//
|
|
||||||
// lfsr_fs_gc will terminate early if it discovers it can no longer
|
|
||||||
// make progress
|
|
||||||
lfs->gc.t.o.o.flags &= ~flags;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1258,35 +1258,6 @@ int lfsr_traversal_read(lfs_t *lfs, lfsr_traversal_t *t,
|
|||||||
int lfsr_traversal_rewind(lfs_t *lfs, lfsr_traversal_t *t);
|
int lfsr_traversal_rewind(lfs_t *lfs, lfsr_traversal_t *t);
|
||||||
|
|
||||||
|
|
||||||
/// Incremental gc operations ///
|
|
||||||
|
|
||||||
#ifdef LFS_GC
|
|
||||||
// Perform any janitorial work that may be pending.
|
|
||||||
//
|
|
||||||
// The exact janitorial work depends on the configured flags and steps.
|
|
||||||
//
|
|
||||||
// Calling this function is not required, but may allow the offloading of
|
|
||||||
// expensive janitorial work to a less time-critical code path.
|
|
||||||
//
|
|
||||||
// Returns a negative error code on failure.
|
|
||||||
int lfsr_gc(lfs_t *lfs);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef LFS_GC
|
|
||||||
// Mark janitorial work as incomplete.
|
|
||||||
//
|
|
||||||
// Any info flags passed to lfsr_gc_unck will be reset internally,
|
|
||||||
// forcing the work to be redone.
|
|
||||||
//
|
|
||||||
// This is most useful for triggering new ckmeta/ckdata scans with
|
|
||||||
// LFS_I_CANCKMETA and LFS_I_CANCKDATA. Otherwise littlefs will perform
|
|
||||||
// only one scan after mount.
|
|
||||||
//
|
|
||||||
// Returns a negative error code on failure.
|
|
||||||
int lfsr_gc_unck(lfs_t *lfs, uint32_t flags);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/// Filesystem-level filesystem operations
|
/// Filesystem-level filesystem operations
|
||||||
|
|
||||||
// Find on-disk info about the filesystem
|
// Find on-disk info about the filesystem
|
||||||
@@ -1341,6 +1312,30 @@ int lfsr_fs_ckmeta(lfs_t *lfs);
|
|||||||
int lfsr_fs_ckdata(lfs_t *lfs);
|
int lfsr_fs_ckdata(lfs_t *lfs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef LFS_GC
|
||||||
|
// Perform any janitorial work that may be pending
|
||||||
|
//
|
||||||
|
// The exact janitorial work depends on the configured flags and steps.
|
||||||
|
//
|
||||||
|
// Calling this function is not required, but may allow the offloading of
|
||||||
|
// expensive janitorial work to a less time-critical code path.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfsr_fs_gc(lfs_t *lfs);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Mark janitorial work as incomplete
|
||||||
|
//
|
||||||
|
// Any info flags passed to lfsr_gc_unck will be reset internally,
|
||||||
|
// forcing the work to be redone.
|
||||||
|
//
|
||||||
|
// This is most useful for triggering new ckmeta/ckdata scans with
|
||||||
|
// LFS_I_CANCKMETA and LFS_I_CANCKDATA. Otherwise littlefs will perform
|
||||||
|
// only one scan after mount.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfsr_fs_unck(lfs_t *lfs, uint32_t flags);
|
||||||
|
|
||||||
#ifndef LFS_READONLY
|
#ifndef LFS_READONLY
|
||||||
// Change the number of blocks used by the filesystem
|
// Change the number of blocks used by the filesystem
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -531,7 +531,7 @@ code = '''
|
|||||||
// try compacting?
|
// try compacting?
|
||||||
#ifdef LFS_GC
|
#ifdef LFS_GC
|
||||||
if (COMPACT) {
|
if (COMPACT) {
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -614,7 +614,7 @@ code = '''
|
|||||||
// try compacting?
|
// try compacting?
|
||||||
#ifdef LFS_GC
|
#ifdef LFS_GC
|
||||||
if (COMPACT) {
|
if (COMPACT) {
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -4119,7 +4119,7 @@ code = '''
|
|||||||
// try compacting?
|
// try compacting?
|
||||||
#ifdef LFS_GC
|
#ifdef LFS_GC
|
||||||
if (COMPACT) {
|
if (COMPACT) {
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -8,7 +8,7 @@ after = ['test_traversal', 'test_gc', 'test_mount']
|
|||||||
# test we can detect at least fully clobbered blocks
|
# test we can detect at least fully clobbered blocks
|
||||||
[cases.test_ck_ckmeta_easy]
|
[cases.test_ck_ckmeta_easy]
|
||||||
# METHOD=0 => lfsr_fs_ckmeta
|
# METHOD=0 => lfsr_fs_ckmeta
|
||||||
# METHOD=1 => lfsr_gc
|
# METHOD=1 => lfsr_fs_gc
|
||||||
# METHOD=2 => lfsr_traversal_read
|
# METHOD=2 => lfsr_traversal_read
|
||||||
# METHOD=3 => lfsr_mount
|
# METHOD=3 => lfsr_mount
|
||||||
defines.METHOD = [0, 1, 2, 3]
|
defines.METHOD = [0, 1, 2, 3]
|
||||||
@@ -99,10 +99,10 @@ code = '''
|
|||||||
if (METHOD == 0) {
|
if (METHOD == 0) {
|
||||||
lfsr_fs_ckmeta(&lfs) => LFS_ERR_CORRUPT;
|
lfsr_fs_ckmeta(&lfs) => LFS_ERR_CORRUPT;
|
||||||
|
|
||||||
// find clobbered blocks with lfsr_gc
|
// find clobbered blocks with lfsr_fs_gc
|
||||||
} else if (METHOD == 1) {
|
} else if (METHOD == 1) {
|
||||||
#ifdef LFS_GC
|
#ifdef LFS_GC
|
||||||
lfsr_gc(&lfs) => LFS_ERR_CORRUPT;
|
lfsr_fs_gc(&lfs) => LFS_ERR_CORRUPT;
|
||||||
#else
|
#else
|
||||||
LFS_UNREACHABLE();
|
LFS_UNREACHABLE();
|
||||||
#endif
|
#endif
|
||||||
@@ -145,7 +145,7 @@ done:;
|
|||||||
|
|
||||||
[cases.test_ck_ckdata_easy]
|
[cases.test_ck_ckdata_easy]
|
||||||
# METHOD=0 => lfsr_fs_ckdata
|
# METHOD=0 => lfsr_fs_ckdata
|
||||||
# METHOD=1 => lfsr_gc
|
# METHOD=1 => lfsr_fs_gc
|
||||||
# METHOD=2 => lfsr_traversal_read
|
# METHOD=2 => lfsr_traversal_read
|
||||||
# METHOD=3 => lfsr_mount
|
# METHOD=3 => lfsr_mount
|
||||||
defines.METHOD = [0, 1, 2, 3]
|
defines.METHOD = [0, 1, 2, 3]
|
||||||
@@ -237,10 +237,10 @@ code = '''
|
|||||||
if (METHOD == 0) {
|
if (METHOD == 0) {
|
||||||
lfsr_fs_ckdata(&lfs) => LFS_ERR_CORRUPT;
|
lfsr_fs_ckdata(&lfs) => LFS_ERR_CORRUPT;
|
||||||
|
|
||||||
// find clobbered blocks with lfsr_gc
|
// find clobbered blocks with lfsr_fs_gc
|
||||||
} else if (METHOD == 1) {
|
} else if (METHOD == 1) {
|
||||||
#ifdef LFS_GC
|
#ifdef LFS_GC
|
||||||
lfsr_gc(&lfs) => LFS_ERR_CORRUPT;
|
lfsr_fs_gc(&lfs) => LFS_ERR_CORRUPT;
|
||||||
#else
|
#else
|
||||||
LFS_UNREACHABLE();
|
LFS_UNREACHABLE();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+55
-53
@@ -52,7 +52,7 @@ code = '''
|
|||||||
// a bit hacky, but this catches infinite loops
|
// a bit hacky, but this catches infinite loops
|
||||||
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
||||||
|
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
|
|
||||||
lfsr_fs_stat(&lfs, &fsinfo) => 0;
|
lfsr_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
if (!(fsinfo.flags & LFS_I_CANLOOKAHEAD)) {
|
if (!(fsinfo.flags & LFS_I_CANLOOKAHEAD)) {
|
||||||
@@ -115,7 +115,7 @@ code = '''
|
|||||||
assert(lfs.omdirs != &lfs.gc.t.o.o);
|
assert(lfs.omdirs != &lfs.gc.t.o.o);
|
||||||
|
|
||||||
// run GC one step
|
// run GC one step
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
assert(lfs.omdirs == &lfs.gc.t.o.o);
|
assert(lfs.omdirs == &lfs.gc.t.o.o);
|
||||||
|
|
||||||
// mutate the filesystem
|
// mutate the filesystem
|
||||||
@@ -129,7 +129,7 @@ code = '''
|
|||||||
|
|
||||||
// run GC until our traversal is done
|
// run GC until our traversal is done
|
||||||
while (lfs.omdirs == &lfs.gc.t.o.o) {
|
while (lfs.omdirs == &lfs.gc.t.o.o) {
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we should _not_ make progress
|
// we should _not_ make progress
|
||||||
@@ -204,7 +204,7 @@ code = '''
|
|||||||
// a bit hacky, but this catches infinite loops
|
// a bit hacky, but this catches infinite loops
|
||||||
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
||||||
|
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
|
|
||||||
lfsr_fs_stat(&lfs, &fsinfo) => 0;
|
lfsr_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
if (!(fsinfo.flags & LFS_I_UNCOMPACTED)) {
|
if (!(fsinfo.flags & LFS_I_UNCOMPACTED)) {
|
||||||
@@ -290,14 +290,14 @@ code = '''
|
|||||||
|
|
||||||
// run GC one traversal + one step
|
// run GC one traversal + one step
|
||||||
while (true) {
|
while (true) {
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
|
|
||||||
// internal traversal done?
|
// internal traversal done?
|
||||||
if (lfs.omdirs != &lfs.gc.t.o.o) {
|
if (lfs.omdirs != &lfs.gc.t.o.o) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
assert(lfs.omdirs == &lfs.gc.t.o.o);
|
assert(lfs.omdirs == &lfs.gc.t.o.o);
|
||||||
|
|
||||||
// mutate the filesystem
|
// mutate the filesystem
|
||||||
@@ -310,7 +310,7 @@ code = '''
|
|||||||
|
|
||||||
// run GC until our traversal is done (twice for compact)
|
// run GC until our traversal is done (twice for compact)
|
||||||
while (lfs.omdirs == &lfs.gc.t.o.o) {
|
while (lfs.omdirs == &lfs.gc.t.o.o) {
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we should _not_ make progress
|
// we should _not_ make progress
|
||||||
@@ -414,7 +414,7 @@ code = '''
|
|||||||
// a bit hacky, but this catches infinite loops
|
// a bit hacky, but this catches infinite loops
|
||||||
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
||||||
|
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
|
|
||||||
lfsr_fs_stat(&lfs, &fsinfo) => 0;
|
lfsr_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
if (!(fsinfo.flags & LFS_I_INCONSISTENT)) {
|
if (!(fsinfo.flags & LFS_I_INCONSISTENT)) {
|
||||||
@@ -606,7 +606,7 @@ code = '''
|
|||||||
|
|
||||||
// run GC one step
|
// run GC one step
|
||||||
assert(lfs.omdirs != &lfs.gc.t.o.o);
|
assert(lfs.omdirs != &lfs.gc.t.o.o);
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
assert(lfs.omdirs == &lfs.gc.t.o.o);
|
assert(lfs.omdirs == &lfs.gc.t.o.o);
|
||||||
|
|
||||||
// create the rest of the orphans after GC has started
|
// create the rest of the orphans after GC has started
|
||||||
@@ -627,7 +627,7 @@ code = '''
|
|||||||
|
|
||||||
// run GC until our traversal is done
|
// run GC until our traversal is done
|
||||||
while (lfs.omdirs == &lfs.gc.t.o.o) {
|
while (lfs.omdirs == &lfs.gc.t.o.o) {
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we should _not_ make progress
|
// we should _not_ make progress
|
||||||
@@ -747,12 +747,12 @@ code = '''
|
|||||||
}
|
}
|
||||||
|
|
||||||
clobbered:;
|
clobbered:;
|
||||||
// running lfsr_gc should eventually find the clobbered block
|
// running lfsr_fs_gc should eventually find the clobbered block
|
||||||
for (lfs_block_t i = 0;; i++) {
|
for (lfs_block_t i = 0;; i++) {
|
||||||
// a bit hacky, but this catches infinite loops
|
// a bit hacky, but this catches infinite loops
|
||||||
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
||||||
|
|
||||||
int err = lfsr_gc(&lfs);
|
int err = lfsr_fs_gc(&lfs);
|
||||||
assert(!err || err == LFS_ERR_CORRUPT);
|
assert(!err || err == LFS_ERR_CORRUPT);
|
||||||
// found it
|
// found it
|
||||||
if (err == LFS_ERR_CORRUPT) {
|
if (err == LFS_ERR_CORRUPT) {
|
||||||
@@ -848,14 +848,14 @@ code = '''
|
|||||||
}
|
}
|
||||||
|
|
||||||
clobbered:;
|
clobbered:;
|
||||||
// running lfsr_gc should eventually find the clobbered block
|
// running lfsr_fs_gc should eventually find the clobbered block
|
||||||
//
|
//
|
||||||
// note LFS_GC_CKDATA implies LFS_GC_CKMETA
|
// note LFS_GC_CKDATA implies LFS_GC_CKMETA
|
||||||
for (lfs_block_t i = 0;; i++) {
|
for (lfs_block_t i = 0;; i++) {
|
||||||
// a bit hacky, but this catches infinite loops
|
// a bit hacky, but this catches infinite loops
|
||||||
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
||||||
|
|
||||||
int err = lfsr_gc(&lfs);
|
int err = lfsr_fs_gc(&lfs);
|
||||||
assert(!err || err == LFS_ERR_CORRUPT);
|
assert(!err || err == LFS_ERR_CORRUPT);
|
||||||
// found it
|
// found it
|
||||||
if (err == LFS_ERR_CORRUPT) {
|
if (err == LFS_ERR_CORRUPT) {
|
||||||
@@ -1046,10 +1046,10 @@ done:;
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
# test we can detect fully clobbered blocks after a ck pass, if we call
|
# test we can detect fully clobbered blocks after a ck pass, if we call
|
||||||
# lfsr_gc_unck
|
# lfsr_fs_unck
|
||||||
[cases.test_gc_ckmeta_unck]
|
[cases.test_gc_ckmeta_unck]
|
||||||
# AFTER=0 => after running lfsr_gc once
|
# AFTER=0 => after running lfsr_fs_gc once
|
||||||
# AFTER=1 => after running lfsr_gc to completion
|
# AFTER=1 => after running lfsr_fs_gc to completion
|
||||||
# AFTER=2 => after lfsr_fs_ckmeta
|
# AFTER=2 => after lfsr_fs_ckmeta
|
||||||
# AFTER=3 => after remounting with LFS_M_CKMETA
|
# AFTER=3 => after remounting with LFS_M_CKMETA
|
||||||
defines.AFTER = [0, 1, 2, 3]
|
defines.AFTER = [0, 1, 2, 3]
|
||||||
@@ -1095,13 +1095,14 @@ code = '''
|
|||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// run lfsr_gc before clobbering, this should not find anything
|
// run lfsr_fs_gc before clobbering, this should not find
|
||||||
|
// anything
|
||||||
|
|
||||||
// run lfsr_gc once
|
// run lfsr_fs_gc once
|
||||||
if (AFTER == 0) {
|
if (AFTER == 0) {
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
|
|
||||||
// run lfsr_gc to completion
|
// run lfsr_fs_gc to completion
|
||||||
} else if (AFTER == 1) {
|
} else if (AFTER == 1) {
|
||||||
while (true) {
|
while (true) {
|
||||||
struct lfs_fsinfo fsinfo;
|
struct lfs_fsinfo fsinfo;
|
||||||
@@ -1110,7 +1111,7 @@ code = '''
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// run lfsr_fs_ckmeta
|
// run lfsr_fs_ckmeta
|
||||||
@@ -1174,14 +1175,14 @@ code = '''
|
|||||||
|
|
||||||
clobbered:;
|
clobbered:;
|
||||||
// clear relevant ck flags
|
// clear relevant ck flags
|
||||||
lfsr_gc_unck(&lfs, LFS_I_CANCKMETA) => 0;
|
lfsr_fs_unck(&lfs, LFS_I_CANCKMETA) => 0;
|
||||||
|
|
||||||
// running lfsr_gc should eventually find the clobbered block
|
// running lfsr_fs_gc should eventually find the clobbered block
|
||||||
for (lfs_block_t i = 0;; i++) {
|
for (lfs_block_t i = 0;; i++) {
|
||||||
// a bit hacky, but this catches infinite loops
|
// a bit hacky, but this catches infinite loops
|
||||||
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
||||||
|
|
||||||
int err = lfsr_gc(&lfs);
|
int err = lfsr_fs_gc(&lfs);
|
||||||
assert(!err || err == LFS_ERR_CORRUPT);
|
assert(!err || err == LFS_ERR_CORRUPT);
|
||||||
// found it
|
// found it
|
||||||
if (err == LFS_ERR_CORRUPT) {
|
if (err == LFS_ERR_CORRUPT) {
|
||||||
@@ -1195,8 +1196,8 @@ done:;
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
[cases.test_gc_ckdata_unck]
|
[cases.test_gc_ckdata_unck]
|
||||||
# AFTER=0 => after running lfsr_gc once
|
# AFTER=0 => after running lfsr_fs_gc once
|
||||||
# AFTER=1 => after running lfsr_gc to completion
|
# AFTER=1 => after running lfsr_fs_gc to completion
|
||||||
# AFTER=2 => after lfsr_fs_ckdata
|
# AFTER=2 => after lfsr_fs_ckdata
|
||||||
# AFTER=3 => after remounting with LFS_M_CKDATA
|
# AFTER=3 => after remounting with LFS_M_CKDATA
|
||||||
defines.AFTER = [0, 1, 2]
|
defines.AFTER = [0, 1, 2]
|
||||||
@@ -1242,13 +1243,14 @@ code = '''
|
|||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// run lfsr_gc before clobbering, this should not find anything
|
// run lfsr_fs_gc before clobbering, this should not find
|
||||||
|
// anything
|
||||||
|
|
||||||
// run lfsr_gc once
|
// run lfsr_fs_gc once
|
||||||
if (AFTER == 0) {
|
if (AFTER == 0) {
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
|
|
||||||
// run lfsr_gc to completion
|
// run lfsr_fs_gc to completion
|
||||||
} else if (AFTER == 1) {
|
} else if (AFTER == 1) {
|
||||||
while (true) {
|
while (true) {
|
||||||
struct lfs_fsinfo fsinfo;
|
struct lfs_fsinfo fsinfo;
|
||||||
@@ -1257,7 +1259,7 @@ code = '''
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// run lfsr_fs_ckdata
|
// run lfsr_fs_ckdata
|
||||||
@@ -1322,16 +1324,16 @@ code = '''
|
|||||||
|
|
||||||
clobbered:;
|
clobbered:;
|
||||||
// clear relevant ck flags
|
// clear relevant ck flags
|
||||||
lfsr_gc_unck(&lfs, LFS_I_CANCKDATA) => 0;
|
lfsr_fs_unck(&lfs, LFS_I_CANCKDATA) => 0;
|
||||||
|
|
||||||
// running lfsr_gc should eventually find the clobbered block
|
// running lfsr_fs_gc should eventually find the clobbered block
|
||||||
//
|
//
|
||||||
// note LFS_GC_CKDATA implies LFS_GC_CKMETA
|
// note LFS_GC_CKDATA implies LFS_GC_CKMETA
|
||||||
for (lfs_block_t i = 0;; i++) {
|
for (lfs_block_t i = 0;; i++) {
|
||||||
// a bit hacky, but this catches infinite loops
|
// a bit hacky, but this catches infinite loops
|
||||||
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
||||||
|
|
||||||
int err = lfsr_gc(&lfs);
|
int err = lfsr_fs_gc(&lfs);
|
||||||
assert(!err || err == LFS_ERR_CORRUPT);
|
assert(!err || err == LFS_ERR_CORRUPT);
|
||||||
// found it
|
// found it
|
||||||
if (err == LFS_ERR_CORRUPT) {
|
if (err == LFS_ERR_CORRUPT) {
|
||||||
@@ -1401,7 +1403,7 @@ code = '''
|
|||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
// gc!
|
// gc!
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the file contents
|
// check the file contents
|
||||||
@@ -1414,7 +1416,7 @@ code = '''
|
|||||||
lfsr_unmount(&lfs) => 0;
|
lfsr_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# pseudo-fuzz test that spamming lfsr_gc_unck doesn't break anything
|
# pseudo-fuzz test that spamming lfsr_fs_unck doesn't break anything
|
||||||
[cases.test_gc_mutation_unck]
|
[cases.test_gc_mutation_unck]
|
||||||
defines.N = 100
|
defines.N = 100
|
||||||
defines.MKCONSISTENT = [false, true]
|
defines.MKCONSISTENT = [false, true]
|
||||||
@@ -1471,10 +1473,10 @@ code = '''
|
|||||||
|
|
||||||
// choose a random set of flags to unck every cycle
|
// choose a random set of flags to unck every cycle
|
||||||
uint32_t flags = GC_FLAGS & TEST_PRNG(&prng);
|
uint32_t flags = GC_FLAGS & TEST_PRNG(&prng);
|
||||||
lfsr_gc_unck(&lfs, flags) => 0;
|
lfsr_fs_unck(&lfs, flags) => 0;
|
||||||
|
|
||||||
// gc!
|
// gc!
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the file contents
|
// check the file contents
|
||||||
@@ -1525,11 +1527,11 @@ code = '''
|
|||||||
assert(!err || (TEST_PLS && err == LFS_ERR_EXIST));
|
assert(!err || (TEST_PLS && err == LFS_ERR_EXIST));
|
||||||
|
|
||||||
// gc!
|
// gc!
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
|
|
||||||
// unck to keep things interesting?
|
// unck to keep things interesting?
|
||||||
if (UNCK) {
|
if (UNCK) {
|
||||||
lfsr_gc_unck(&lfs, LFS_I_CANCKMETA | LFS_I_CANCKDATA) => 0;
|
lfsr_fs_unck(&lfs, LFS_I_CANCKMETA | LFS_I_CANCKDATA) => 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1712,11 +1714,11 @@ code = '''
|
|||||||
}
|
}
|
||||||
|
|
||||||
// gc!
|
// gc!
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
|
|
||||||
// unck to keep things interesting?
|
// unck to keep things interesting?
|
||||||
if (UNCK) {
|
if (UNCK) {
|
||||||
lfsr_gc_unck(&lfs, LFS_I_CANCKMETA | LFS_I_CANCKDATA) => 0;
|
lfsr_fs_unck(&lfs, LFS_I_CANCKMETA | LFS_I_CANCKDATA) => 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1824,11 +1826,11 @@ code = '''
|
|||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
// gc!
|
// gc!
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
|
|
||||||
// unck to keep things interesting?
|
// unck to keep things interesting?
|
||||||
if (UNCK) {
|
if (UNCK) {
|
||||||
lfsr_gc_unck(&lfs, LFS_I_CANCKMETA | LFS_I_CANCKDATA) => 0;
|
lfsr_fs_unck(&lfs, LFS_I_CANCKMETA | LFS_I_CANCKDATA) => 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2032,11 +2034,11 @@ code = '''
|
|||||||
}
|
}
|
||||||
|
|
||||||
// gc!
|
// gc!
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
|
|
||||||
// unck to keep things interesting?
|
// unck to keep things interesting?
|
||||||
if (UNCK) {
|
if (UNCK) {
|
||||||
lfsr_gc_unck(&lfs, LFS_I_CANCKMETA | LFS_I_CANCKDATA) => 0;
|
lfsr_fs_unck(&lfs, LFS_I_CANCKMETA | LFS_I_CANCKDATA) => 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2205,11 +2207,11 @@ code = '''
|
|||||||
}
|
}
|
||||||
|
|
||||||
// gc!
|
// gc!
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
|
|
||||||
// unck to keep things interesting?
|
// unck to keep things interesting?
|
||||||
if (UNCK) {
|
if (UNCK) {
|
||||||
lfsr_gc_unck(&lfs, LFS_I_CANCKMETA | LFS_I_CANCKDATA) => 0;
|
lfsr_fs_unck(&lfs, LFS_I_CANCKMETA | LFS_I_CANCKDATA) => 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2544,11 +2546,11 @@ code = '''
|
|||||||
}
|
}
|
||||||
|
|
||||||
// gc!
|
// gc!
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
|
|
||||||
// unck to keep things interesting?
|
// unck to keep things interesting?
|
||||||
if (UNCK) {
|
if (UNCK) {
|
||||||
lfsr_gc_unck(&lfs, LFS_I_CANCKMETA | LFS_I_CANCKDATA) => 0;
|
lfsr_fs_unck(&lfs, LFS_I_CANCKMETA | LFS_I_CANCKDATA) => 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2971,11 +2973,11 @@ code = '''
|
|||||||
}
|
}
|
||||||
|
|
||||||
// gc!
|
// gc!
|
||||||
lfsr_gc(&lfs) => 0;
|
lfsr_fs_gc(&lfs) => 0;
|
||||||
|
|
||||||
// unck to keep things interesting?
|
// unck to keep things interesting?
|
||||||
if (UNCK) {
|
if (UNCK) {
|
||||||
lfsr_gc_unck(&lfs, LFS_I_CANCKMETA | LFS_I_CANCKDATA) => 0;
|
lfsr_fs_unck(&lfs, LFS_I_CANCKMETA | LFS_I_CANCKDATA) => 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user