Changed gc_steps into a runtime parameter, better dedup mount gc
So instead of configuring gc_steps at mount time (or eventually compile
time), lfsr_fs_gc now takes a steps parameter that controls how much gc
work to attempt:
int lfsr_fs_gc(lfs_t *lfs, lfs_soff_t steps, uint32_t flags);
This API was needed internally to better deduplicate on-mount gc, and I
figured it might also be useful for users to be able to easily change
gc_steps per lfsr_fs_gc call.
I realize this could also be accomplished with the theoretical
lfsr_fs_gccfg, but it's a bit easier to not need a struct every call.
Most likely, depending on project/system, users will always call
lfsr_fs_gc with either 1 (minimal work) or -1 (maximal work), or, worst
case, can define a system-wide GC_STEPS somewhere.
---
Deduplicating on-mount gc work better saved some code, though it's worth
noting this could have been done internally and not exposed to users:
code stack
before: 36476 2680 (+0.0%)
after: 36316 (-0.4%) 2680 (+0.0%)
This commit is contained in:
@@ -12623,13 +12623,13 @@ int lfsr_mount(lfs_t *lfs, uint32_t flags,
|
|||||||
|
|
||||||
int err = lfs_init(lfs,
|
int err = lfs_init(lfs,
|
||||||
// strip out the one-time traversal flags
|
// strip out the one-time traversal flags
|
||||||
flags
|
flags & ~(
|
||||||
& ~LFS_M_MTREEONLY
|
LFS_M_MTREEONLY
|
||||||
& ~LFS_M_MKCONSISTENT
|
| LFS_M_MKCONSISTENT
|
||||||
& ~LFS_M_LOOKAHEAD
|
| LFS_M_LOOKAHEAD
|
||||||
& ~LFS_M_COMPACT
|
| LFS_M_COMPACT
|
||||||
& ~LFS_M_CKMETA
|
| LFS_M_CKMETA
|
||||||
& ~LFS_M_CKDATA,
|
| LFS_M_CKDATA),
|
||||||
cfg);
|
cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
@@ -12655,74 +12655,18 @@ int lfsr_mount(lfs_t *lfs, uint32_t flags,
|
|||||||
lfsr_mtree_weight_(&lfs->mtree) >> lfs->mdir_bits,
|
lfsr_mtree_weight_(&lfs->mtree) >> lfs->mdir_bits,
|
||||||
1 << lfs->mdir_bits);
|
1 << lfs->mdir_bits);
|
||||||
|
|
||||||
// fix pending grms if requested
|
// run gc if requested
|
||||||
if (lfsr_t_ismkconsistent(flags)
|
err = lfsr_fs_gc(lfs, -1,
|
||||||
&& lfsr_grm_count(lfs) > 0) {
|
flags & (
|
||||||
if (lfsr_grm_count(lfs) == 2) {
|
LFS_M_MTREEONLY
|
||||||
LFS_DEBUG("Fixing grm %"PRId32".%"PRId32" %"PRId32".%"PRId32,
|
| LFS_M_MKCONSISTENT
|
||||||
lfsr_mid_bid(lfs, lfs->grm.mids[0]) >> lfs->mdir_bits,
|
| LFS_M_LOOKAHEAD
|
||||||
lfsr_mid_rid(lfs, lfs->grm.mids[0]),
|
| LFS_M_COMPACT
|
||||||
lfsr_mid_bid(lfs, lfs->grm.mids[1]) >> lfs->mdir_bits,
|
| LFS_M_CKMETA
|
||||||
lfsr_mid_rid(lfs, lfs->grm.mids[1]));
|
| LFS_M_CKDATA));
|
||||||
} else if (lfsr_grm_count(lfs) == 1) {
|
|
||||||
LFS_DEBUG("Fixing grm %"PRId32".%"PRId32,
|
|
||||||
lfsr_mid_bid(lfs, lfs->grm.mids[0]) >> lfs->mdir_bits,
|
|
||||||
lfsr_mid_rid(lfs, lfs->grm.mids[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
err = lfsr_fs_fixgrm(lfs);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// run gc until all requested mount work is done
|
|
||||||
bool mutated = true;
|
|
||||||
while ((lfsr_t_ismkconsistent(flags)
|
|
||||||
&& lfsr_f_hasorphans(lfs->flags))
|
|
||||||
|| (lfsr_t_islookahead(flags)
|
|
||||||
&& lfsr_fs_canlookahead(lfs))
|
|
||||||
|| (lfsr_t_iscompact(flags)
|
|
||||||
&& lfsr_i_isuncompacted(lfs->flags))
|
|
||||||
|| (lfsr_t_isckmeta(flags)
|
|
||||||
&& mutated)
|
|
||||||
|| (lfsr_t_isckdata(flags)
|
|
||||||
&& mutated)) {
|
|
||||||
|
|
||||||
// checkpoint the allocator to maximize any lookahead scans
|
|
||||||
lfs_alloc_ckpoint(lfs);
|
|
||||||
|
|
||||||
// do we really need a full traversal?
|
|
||||||
uint32_t flags_ = flags;
|
|
||||||
if (!((lfsr_t_islookahead(flags)
|
|
||||||
&& lfsr_fs_canlookahead(lfs))
|
|
||||||
|| (lfsr_t_iscompact(flags)
|
|
||||||
&& lfsr_i_isuncompacted(lfs->flags))
|
|
||||||
|| (lfsr_t_isckmeta(flags)
|
|
||||||
&& mutated)
|
|
||||||
|| (lfsr_t_isckdata(flags)
|
|
||||||
&& mutated))) {
|
|
||||||
flags_ |= LFS_GC_MTREEONLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
lfsr_traversal_t t = LFSR_TRAVERSAL(flags_);
|
|
||||||
lfsr_omdir_open(lfs, &t.o.o);
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
err = lfsr_mtree_gc(lfs, &t,
|
|
||||||
NULL, NULL);
|
|
||||||
if (err) {
|
|
||||||
lfsr_omdir_close(lfs, &t.o.o);
|
|
||||||
if (err == LFS_ERR_NOENT) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mutated? we need another pass for ckmeta/ckdata
|
|
||||||
mutated = lfsr_f_ismutated(t.o.o.flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -13078,10 +13022,7 @@ int lfsr_fs_ckdata(lfs_t *lfs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// perform any pending janitorial work
|
// perform any pending janitorial work
|
||||||
int lfsr_fs_gc(lfs_t *lfs, uint32_t flags) {
|
int lfsr_fs_gc(lfs_t *lfs, lfs_soff_t steps, uint32_t flags) {
|
||||||
// some flags don't make sense when only traversing the mtree
|
|
||||||
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_islookahead(flags));
|
|
||||||
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_isckdata(flags));
|
|
||||||
// unknown flags?
|
// unknown flags?
|
||||||
LFS_ASSERT((flags
|
LFS_ASSERT((flags
|
||||||
& ~LFS_GC_MTREEONLY
|
& ~LFS_GC_MTREEONLY
|
||||||
@@ -13090,6 +13031,9 @@ int lfsr_fs_gc(lfs_t *lfs, uint32_t flags) {
|
|||||||
& ~LFS_GC_COMPACT
|
& ~LFS_GC_COMPACT
|
||||||
& ~LFS_GC_CKMETA
|
& ~LFS_GC_CKMETA
|
||||||
& ~LFS_GC_CKDATA) == 0);
|
& ~LFS_GC_CKDATA) == 0);
|
||||||
|
// some flags don't make sense when only traversing the mtree
|
||||||
|
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_islookahead(flags));
|
||||||
|
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_isckdata(flags));
|
||||||
|
|
||||||
// fix pending grms if requested
|
// fix pending grms if requested
|
||||||
if (lfsr_t_ismkconsistent(flags)
|
if (lfsr_t_ismkconsistent(flags)
|
||||||
@@ -13112,31 +13056,22 @@ int lfsr_fs_gc(lfs_t *lfs, uint32_t flags) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// do we need to do anything?
|
// do we have any pending work?
|
||||||
if (!((lfsr_t_ismkconsistent(flags)
|
bool cked = false;
|
||||||
|
while ((lfs_off_t)steps > 0
|
||||||
|
&& ((lfsr_t_ismkconsistent(flags)
|
||||||
&& lfsr_f_hasorphans(lfs->flags))
|
&& lfsr_f_hasorphans(lfs->flags))
|
||||||
|| (lfsr_t_islookahead(flags)
|
|| (lfsr_t_islookahead(flags)
|
||||||
&& lfsr_fs_canlookahead(lfs))
|
&& lfsr_fs_canlookahead(lfs))
|
||||||
|| (lfsr_t_iscompact(flags)
|
|| (lfsr_t_iscompact(flags)
|
||||||
&& lfsr_i_isuncompacted(lfs->flags))
|
&& lfsr_i_isuncompacted(lfs->flags))
|
||||||
|| lfsr_t_isckmeta(flags)
|
|| (lfsr_t_isckmeta(flags)
|
||||||
|| lfsr_t_isckdata(flags))) {
|
&& !cked)
|
||||||
return 0;
|
|| (lfsr_t_isckdata(flags)
|
||||||
}
|
&& !cked))) {
|
||||||
|
|
||||||
// checkpoint the allocator to maximize any lookahead scans
|
// checkpoint the allocator to maximize any lookahead scans
|
||||||
lfs_alloc_ckpoint(lfs);
|
lfs_alloc_ckpoint(lfs);
|
||||||
|
|
||||||
// do we really need a full traversal?
|
|
||||||
if (!((lfsr_t_islookahead(flags)
|
|
||||||
&& lfsr_fs_canlookahead(lfs))
|
|
||||||
|| (lfsr_t_iscompact(flags)
|
|
||||||
&& lfsr_i_isuncompacted(lfs->flags))
|
|
||||||
|| lfsr_t_isckmeta(flags)
|
|
||||||
|| lfsr_t_isckdata(flags))) {
|
|
||||||
flags |= LFS_GC_MTREEONLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// existing traversal?
|
// existing traversal?
|
||||||
if (lfsr_omdir_isopen(lfs, &lfs->gc.o.o)) {
|
if (lfsr_omdir_isopen(lfs, &lfs->gc.o.o)) {
|
||||||
// note that we mask flags (except mtreeonly)! if you change flags
|
// note that we mask flags (except mtreeonly)! if you change flags
|
||||||
@@ -13151,18 +13086,40 @@ int lfsr_fs_gc(lfs_t *lfs, uint32_t flags) {
|
|||||||
) | flags;
|
) | flags;
|
||||||
// start a new traversal
|
// start a new traversal
|
||||||
} else {
|
} else {
|
||||||
lfs->gc = LFSR_TRAVERSAL(flags);
|
lfs->gc = LFSR_TRAVERSAL(
|
||||||
|
flags
|
||||||
|
// do we really need a full traversal?
|
||||||
|
| ((!((lfsr_t_islookahead(flags)
|
||||||
|
&& lfsr_fs_canlookahead(lfs))
|
||||||
|
|| (lfsr_t_iscompact(flags)
|
||||||
|
&& lfsr_i_isuncompacted(lfs->flags))
|
||||||
|
|| (lfsr_t_isckmeta(flags)
|
||||||
|
&& !cked)
|
||||||
|
|| (lfsr_t_isckdata(flags)
|
||||||
|
&& !cked)))
|
||||||
|
? LFS_T_MTREEONLY
|
||||||
|
: 0));
|
||||||
lfsr_omdir_open(lfs, &lfs->gc.o.o);
|
lfsr_omdir_open(lfs, &lfs->gc.o.o);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0;
|
// progress gc
|
||||||
i < (lfs->cfg->gc_steps ? (uint32_t)lfs->cfg->gc_steps : 1);
|
|
||||||
i++) {
|
|
||||||
int err = lfsr_mtree_gc(lfs, &lfs->gc,
|
int err = lfsr_mtree_gc(lfs, &lfs->gc,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
if (err) {
|
if (err && err != LFS_ERR_NOENT) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == LFS_ERR_NOENT) {
|
||||||
lfsr_omdir_close(lfs, &lfs->gc.o.o);
|
lfsr_omdir_close(lfs, &lfs->gc.o.o);
|
||||||
return (err == LFS_ERR_NOENT) ? 0 : err;
|
|
||||||
|
// consider our filesystem checked if we completed a traversal
|
||||||
|
// with no mutation
|
||||||
|
cked = !lfsr_f_ismutated(lfs->gc.o.o.flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
// decrement steps
|
||||||
|
if (steps > 0) {
|
||||||
|
steps -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -310,17 +310,6 @@ struct lfs_config {
|
|||||||
// can track 8 blocks.
|
// can track 8 blocks.
|
||||||
lfs_size_t lookahead_size;
|
lfs_size_t lookahead_size;
|
||||||
|
|
||||||
// How many gc steps to perform on each lfsr_fs_gc call.
|
|
||||||
//
|
|
||||||
// Each gc step progresses janitorial work by ~1 block (this is equivalent
|
|
||||||
// to lfsr_traversal_read). More steps per call may make more progress if
|
|
||||||
// interleaving with other work.
|
|
||||||
//
|
|
||||||
// 0 defaults to 1 step, and -1 will perform a full traversal every call,
|
|
||||||
// though multiple traversals may still be needed to complete all
|
|
||||||
// janitorial work.
|
|
||||||
int32_t gc_steps;
|
|
||||||
|
|
||||||
// Threshold for metadata compaction during gc in bytes. Metadata logs
|
// Threshold for metadata compaction during gc in bytes. Metadata logs
|
||||||
// that exceed this threshold will be compacted during gc operations.
|
// that exceed this threshold will be compacted during gc operations.
|
||||||
// Defaults to ~88% block_size when zero, though this default may change
|
// Defaults to ~88% block_size when zero, though this default may change
|
||||||
@@ -1183,14 +1172,20 @@ int lfsr_fs_ckdata(lfs_t *lfs);
|
|||||||
#ifndef LFS_READONLY
|
#ifndef LFS_READONLY
|
||||||
// Perform any janitorial work that may be pending.
|
// Perform any janitorial work that may be pending.
|
||||||
//
|
//
|
||||||
// The exact janitorial work depends on the provided flags. Note multiple
|
// The exact janitorial work depends on the provided flags.
|
||||||
// calls may be required to complete all janitorial work.
|
//
|
||||||
|
// The steps parameter controls how many gc steps to progress before
|
||||||
|
// returning, with each gc step being ~1 block of work. More steps per call
|
||||||
|
// will make more progress if interleaved with other filesystem writes, but
|
||||||
|
// may also introduce more latency. steps=1 will do the minimum amount of
|
||||||
|
// work to make progress, and steps=-1 will not return until all pending
|
||||||
|
// janitorial work has been completed.
|
||||||
//
|
//
|
||||||
// Calling this function is not required, but may allow the offloading of
|
// Calling this function is not required, but may allow the offloading of
|
||||||
// expensive janitorial work to a less time-critical code path.
|
// expensive janitorial work to a less time-critical code path.
|
||||||
//
|
//
|
||||||
// Returns a negative error code on failure.
|
// Returns a negative error code on failure.
|
||||||
int lfsr_fs_gc(lfs_t *lfs, uint32_t flags);
|
int lfsr_fs_gc(lfs_t *lfs, lfs_soff_t steps, uint32_t flags);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LFS_READONLY
|
#ifndef LFS_READONLY
|
||||||
|
|||||||
@@ -120,7 +120,6 @@ void bench_permutation(size_t i, uint32_t *buffer, size_t size);
|
|||||||
BENCH_DEFINE(PCACHE_SIZE, LFS_MAX(16, PROG_SIZE) ) \
|
BENCH_DEFINE(PCACHE_SIZE, LFS_MAX(16, PROG_SIZE) ) \
|
||||||
BENCH_DEFINE(FILE_BUFFER_SIZE, 16 ) \
|
BENCH_DEFINE(FILE_BUFFER_SIZE, 16 ) \
|
||||||
BENCH_DEFINE(LOOKAHEAD_SIZE, 16 ) \
|
BENCH_DEFINE(LOOKAHEAD_SIZE, 16 ) \
|
||||||
BENCH_DEFINE(GC_STEPS, 0 ) \
|
|
||||||
BENCH_DEFINE(GC_COMPACT_THRESH, 0 ) \
|
BENCH_DEFINE(GC_COMPACT_THRESH, 0 ) \
|
||||||
BENCH_DEFINE(INLINE_SIZE, BLOCK_SIZE/4 ) \
|
BENCH_DEFINE(INLINE_SIZE, BLOCK_SIZE/4 ) \
|
||||||
BENCH_DEFINE(SHRUB_SIZE, INLINE_SIZE ) \
|
BENCH_DEFINE(SHRUB_SIZE, INLINE_SIZE ) \
|
||||||
@@ -150,7 +149,6 @@ void bench_permutation(size_t i, uint32_t *buffer, size_t size);
|
|||||||
.pcache_size = PCACHE_SIZE, \
|
.pcache_size = PCACHE_SIZE, \
|
||||||
.file_buffer_size = FILE_BUFFER_SIZE, \
|
.file_buffer_size = FILE_BUFFER_SIZE, \
|
||||||
.lookahead_size = LOOKAHEAD_SIZE, \
|
.lookahead_size = LOOKAHEAD_SIZE, \
|
||||||
.gc_steps = GC_STEPS, \
|
|
||||||
.gc_compact_thresh = GC_COMPACT_THRESH, \
|
.gc_compact_thresh = GC_COMPACT_THRESH, \
|
||||||
.inline_size = INLINE_SIZE, \
|
.inline_size = INLINE_SIZE, \
|
||||||
.shrub_size = SHRUB_SIZE, \
|
.shrub_size = SHRUB_SIZE, \
|
||||||
|
|||||||
@@ -105,7 +105,6 @@ void test_permutation(size_t i, uint32_t *buffer, size_t size);
|
|||||||
TEST_DEFINE(PCACHE_SIZE, LFS_MAX(16, PROG_SIZE) ) \
|
TEST_DEFINE(PCACHE_SIZE, LFS_MAX(16, PROG_SIZE) ) \
|
||||||
TEST_DEFINE(FILE_BUFFER_SIZE, 16 ) \
|
TEST_DEFINE(FILE_BUFFER_SIZE, 16 ) \
|
||||||
TEST_DEFINE(LOOKAHEAD_SIZE, 16 ) \
|
TEST_DEFINE(LOOKAHEAD_SIZE, 16 ) \
|
||||||
TEST_DEFINE(GC_STEPS, 0 ) \
|
|
||||||
TEST_DEFINE(GC_COMPACT_THRESH, 0 ) \
|
TEST_DEFINE(GC_COMPACT_THRESH, 0 ) \
|
||||||
TEST_DEFINE(INLINE_SIZE, BLOCK_SIZE/4 ) \
|
TEST_DEFINE(INLINE_SIZE, BLOCK_SIZE/4 ) \
|
||||||
TEST_DEFINE(SHRUB_SIZE, INLINE_SIZE ) \
|
TEST_DEFINE(SHRUB_SIZE, INLINE_SIZE ) \
|
||||||
@@ -135,7 +134,6 @@ void test_permutation(size_t i, uint32_t *buffer, size_t size);
|
|||||||
.pcache_size = PCACHE_SIZE, \
|
.pcache_size = PCACHE_SIZE, \
|
||||||
.file_buffer_size = FILE_BUFFER_SIZE, \
|
.file_buffer_size = FILE_BUFFER_SIZE, \
|
||||||
.lookahead_size = LOOKAHEAD_SIZE, \
|
.lookahead_size = LOOKAHEAD_SIZE, \
|
||||||
.gc_steps = GC_STEPS, \
|
|
||||||
.gc_compact_thresh = GC_COMPACT_THRESH, \
|
.gc_compact_thresh = GC_COMPACT_THRESH, \
|
||||||
.inline_size = INLINE_SIZE, \
|
.inline_size = INLINE_SIZE, \
|
||||||
.shrub_size = SHRUB_SIZE, \
|
.shrub_size = SHRUB_SIZE, \
|
||||||
|
|||||||
+68
-75
@@ -41,23 +41,22 @@ code = '''
|
|||||||
assert(fsinfo.flags & LFS_I_CANLOOKAHEAD);
|
assert(fsinfo.flags & LFS_I_CANLOOKAHEAD);
|
||||||
assert(lfs.omdirs != &lfs.gc.o.o);
|
assert(lfs.omdirs != &lfs.gc.o.o);
|
||||||
|
|
||||||
// run GC until our traversal is done
|
// run GC until we make progress
|
||||||
while (true) {
|
for (lfs_block_t i = 0;; i++) {
|
||||||
lfsr_fs_gc(&lfs,
|
// a bit hacky, but this catches infinite loops
|
||||||
|
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
||||||
|
|
||||||
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
LFS_GC_LOOKAHEAD
|
LFS_GC_LOOKAHEAD
|
||||||
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
||||||
|
|
||||||
// internal traversal done?
|
lfsr_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
if (lfs.omdirs != &lfs.gc.o.o) {
|
if (!(fsinfo.flags & LFS_I_CANLOOKAHEAD)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we should have made progress
|
|
||||||
lfsr_fs_stat(&lfs, &fsinfo) => 0;
|
|
||||||
assert(!(fsinfo.flags & LFS_I_CANLOOKAHEAD));
|
|
||||||
|
|
||||||
// check the file contents
|
// check the file contents
|
||||||
lfsr_file_open(&lfs, &file, "spider", LFS_O_RDONLY) => 0;
|
lfsr_file_open(&lfs, &file, "spider", LFS_O_RDONLY) => 0;
|
||||||
uint8_t rbuf[SIZE];
|
uint8_t rbuf[SIZE];
|
||||||
@@ -106,7 +105,7 @@ code = '''
|
|||||||
assert(lfs.omdirs != &lfs.gc.o.o);
|
assert(lfs.omdirs != &lfs.gc.o.o);
|
||||||
|
|
||||||
// run GC one step
|
// run GC one step
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
LFS_GC_LOOKAHEAD
|
LFS_GC_LOOKAHEAD
|
||||||
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
||||||
@@ -123,7 +122,7 @@ code = '''
|
|||||||
|
|
||||||
// run GC until our traversal is done
|
// run GC until our traversal is done
|
||||||
while (lfs.omdirs == &lfs.gc.o.o) {
|
while (lfs.omdirs == &lfs.gc.o.o) {
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
LFS_GC_LOOKAHEAD
|
LFS_GC_LOOKAHEAD
|
||||||
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
||||||
@@ -183,14 +182,14 @@ code = '''
|
|||||||
assert(lfs.omdirs != &lfs.gc.o.o);
|
assert(lfs.omdirs != &lfs.gc.o.o);
|
||||||
|
|
||||||
// run GC one step
|
// run GC one step
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
((CKMETA) ? LFS_GC_CKMETA : 0)
|
((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
||||||
assert(lfs.omdirs == &lfs.gc.o.o);
|
assert(lfs.omdirs == &lfs.gc.o.o);
|
||||||
|
|
||||||
// change flags and run GC until our traversal is done
|
// change flags and run GC until our traversal is done
|
||||||
while (lfs.omdirs == &lfs.gc.o.o) {
|
while (lfs.omdirs == &lfs.gc.o.o) {
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
LFS_GC_LOOKAHEAD
|
LFS_GC_LOOKAHEAD
|
||||||
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
||||||
@@ -250,7 +249,7 @@ code = '''
|
|||||||
assert(lfs.omdirs != &lfs.gc.o.o);
|
assert(lfs.omdirs != &lfs.gc.o.o);
|
||||||
|
|
||||||
// run GC one step
|
// run GC one step
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
LFS_GC_LOOKAHEAD
|
LFS_GC_LOOKAHEAD
|
||||||
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
||||||
@@ -258,7 +257,7 @@ code = '''
|
|||||||
|
|
||||||
// change flags and run GC until our traversal is done
|
// change flags and run GC until our traversal is done
|
||||||
while (lfs.omdirs == &lfs.gc.o.o) {
|
while (lfs.omdirs == &lfs.gc.o.o) {
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
((CKMETA) ? LFS_GC_CKMETA : 0)
|
((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
||||||
}
|
}
|
||||||
@@ -323,29 +322,26 @@ code = '''
|
|||||||
assert(fsinfo.flags & LFS_I_UNCOMPACTED);
|
assert(fsinfo.flags & LFS_I_UNCOMPACTED);
|
||||||
assert(lfs.omdirs != &lfs.gc.o.o);
|
assert(lfs.omdirs != &lfs.gc.o.o);
|
||||||
|
|
||||||
// run GC until our traversal is done (twice for compact)
|
// run GC until we make progress
|
||||||
for (int i = 0; i < 2; i++) {
|
for (lfs_block_t i = 0;; i++) {
|
||||||
while (true) {
|
// a bit hacky, but this catches infinite loops
|
||||||
lfsr_fs_gc(&lfs,
|
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
||||||
|
|
||||||
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
LFS_GC_COMPACT
|
LFS_GC_COMPACT
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
||||||
|
|
||||||
// internal traversal done?
|
lfsr_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
if (lfs.omdirs != &lfs.gc.o.o) {
|
if (!(fsinfo.flags & LFS_I_UNCOMPACTED)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// mdir should have been compacted
|
// mdir should have been compacted
|
||||||
assert((file.o.o.mdir.rbyd.eoff & 0x7fffffff) <= GC_COMPACT_THRESH);
|
assert((file.o.o.mdir.rbyd.eoff & 0x7fffffff) <= GC_COMPACT_THRESH);
|
||||||
|
|
||||||
// we should have made progress
|
|
||||||
lfsr_fs_stat(&lfs, &fsinfo) => 0;
|
|
||||||
assert(!(fsinfo.flags & LFS_I_UNCOMPACTED));
|
|
||||||
|
|
||||||
// check we can still read the file
|
// check we can still read the file
|
||||||
for (int remount = 0; remount < 2; remount++) {
|
for (int remount = 0; remount < 2; remount++) {
|
||||||
// remount?
|
// remount?
|
||||||
@@ -413,7 +409,7 @@ code = '''
|
|||||||
|
|
||||||
// run GC one traversal + one step
|
// run GC one traversal + one step
|
||||||
while (true) {
|
while (true) {
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
LFS_GC_COMPACT
|
LFS_GC_COMPACT
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
@@ -424,7 +420,7 @@ code = '''
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
LFS_GC_COMPACT
|
LFS_GC_COMPACT
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
@@ -441,7 +437,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.o.o) {
|
while (lfs.omdirs == &lfs.gc.o.o) {
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
LFS_GC_COMPACT
|
LFS_GC_COMPACT
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
@@ -521,7 +517,7 @@ code = '''
|
|||||||
|
|
||||||
// run GC one traversal + one step
|
// run GC one traversal + one step
|
||||||
while (true) {
|
while (true) {
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
||||||
@@ -531,7 +527,7 @@ code = '''
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
||||||
@@ -539,7 +535,7 @@ code = '''
|
|||||||
|
|
||||||
// change flags and run GC until our traversal is done (twice for compact)
|
// change flags and run GC until our traversal is done (twice for compact)
|
||||||
while (lfs.omdirs == &lfs.gc.o.o) {
|
while (lfs.omdirs == &lfs.gc.o.o) {
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
LFS_GC_COMPACT
|
LFS_GC_COMPACT
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
@@ -619,7 +615,7 @@ code = '''
|
|||||||
|
|
||||||
// run GC one traversal + one step
|
// run GC one traversal + one step
|
||||||
while (true) {
|
while (true) {
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
LFS_GC_COMPACT
|
LFS_GC_COMPACT
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
@@ -630,7 +626,7 @@ code = '''
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
LFS_GC_COMPACT
|
LFS_GC_COMPACT
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
@@ -639,7 +635,7 @@ code = '''
|
|||||||
|
|
||||||
// change flags and run GC until our traversal is done (twice for compact)
|
// change flags and run GC until our traversal is done (twice for compact)
|
||||||
while (lfs.omdirs == &lfs.gc.o.o) {
|
while (lfs.omdirs == &lfs.gc.o.o) {
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
||||||
@@ -733,25 +729,24 @@ code = '''
|
|||||||
assert(fsinfo.flags & LFS_I_INCONSISTENT);
|
assert(fsinfo.flags & LFS_I_INCONSISTENT);
|
||||||
assert(lfs.omdirs != &lfs.gc.o.o);
|
assert(lfs.omdirs != &lfs.gc.o.o);
|
||||||
|
|
||||||
// run GC until our traversal is done
|
// run GC until we make progress
|
||||||
while (true) {
|
for (lfs_block_t i = 0;; i++) {
|
||||||
lfsr_fs_gc(&lfs,
|
// a bit hacky, but this catches infinite loops
|
||||||
|
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
||||||
|
|
||||||
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
LFS_GC_MKCONSISTENT
|
LFS_GC_MKCONSISTENT
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
||||||
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
| ((CKDATA) ? LFS_GC_CKDATA : 0)) => 0;
|
||||||
|
|
||||||
// internal traversal done?
|
lfsr_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
if (lfs.omdirs != &lfs.gc.o.o) {
|
if (!(fsinfo.flags & LFS_I_INCONSISTENT)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we should have made progress
|
|
||||||
lfsr_fs_stat(&lfs, &fsinfo) => 0;
|
|
||||||
assert(!(fsinfo.flags & LFS_I_INCONSISTENT));
|
|
||||||
|
|
||||||
// check we can still read the files
|
// check we can still read the files
|
||||||
for (int remount = 0; remount < 2; remount++) {
|
for (int remount = 0; remount < 2; remount++) {
|
||||||
// remount?
|
// remount?
|
||||||
@@ -925,7 +920,7 @@ code = '''
|
|||||||
|
|
||||||
// run GC one step
|
// run GC one step
|
||||||
assert(lfs.omdirs != &lfs.gc.o.o);
|
assert(lfs.omdirs != &lfs.gc.o.o);
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
LFS_GC_MKCONSISTENT
|
LFS_GC_MKCONSISTENT
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
||||||
@@ -951,7 +946,7 @@ code = '''
|
|||||||
|
|
||||||
// run GC until our traversal is done
|
// run GC until our traversal is done
|
||||||
while (lfs.omdirs == &lfs.gc.o.o) {
|
while (lfs.omdirs == &lfs.gc.o.o) {
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
LFS_GC_MKCONSISTENT
|
LFS_GC_MKCONSISTENT
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
||||||
@@ -1057,7 +1052,7 @@ code = '''
|
|||||||
assert(lfs.omdirs != &lfs.gc.o.o);
|
assert(lfs.omdirs != &lfs.gc.o.o);
|
||||||
|
|
||||||
// run GC one step
|
// run GC one step
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
||||||
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
@@ -1066,7 +1061,7 @@ code = '''
|
|||||||
|
|
||||||
// change flags and run GC until our traversal is done
|
// change flags and run GC until our traversal is done
|
||||||
while (lfs.omdirs == &lfs.gc.o.o) {
|
while (lfs.omdirs == &lfs.gc.o.o) {
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
LFS_GC_MKCONSISTENT
|
LFS_GC_MKCONSISTENT
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
||||||
@@ -1171,7 +1166,7 @@ code = '''
|
|||||||
assert(lfs.omdirs != &lfs.gc.o.o);
|
assert(lfs.omdirs != &lfs.gc.o.o);
|
||||||
|
|
||||||
// run GC one step
|
// run GC one step
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
LFS_GC_MKCONSISTENT
|
LFS_GC_MKCONSISTENT
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
||||||
@@ -1181,7 +1176,7 @@ code = '''
|
|||||||
|
|
||||||
// change flags and run GC until our traversal is done
|
// change flags and run GC until our traversal is done
|
||||||
while (lfs.omdirs == &lfs.gc.o.o) {
|
while (lfs.omdirs == &lfs.gc.o.o) {
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
||||||
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
| ((CKMETA) ? LFS_GC_CKMETA : 0)
|
||||||
@@ -1302,17 +1297,16 @@ code = '''
|
|||||||
|
|
||||||
clobbered:;
|
clobbered:;
|
||||||
// running lfsr_fs_gc should eventually find the clobbered block
|
// running lfsr_fs_gc should eventually find the clobbered block
|
||||||
while (true) {
|
for (lfs_block_t i = 0;; i++) {
|
||||||
int err = lfsr_fs_gc(&lfs, LFS_GC_CKMETA);
|
// a bit hacky, but this catches infinite loops
|
||||||
|
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
||||||
|
|
||||||
|
int err = lfsr_fs_gc(&lfs, GC_STEPS, LFS_GC_CKMETA);
|
||||||
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) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we should find the clobbered block before finishing the
|
|
||||||
// traversal
|
|
||||||
assert(lfs.omdirs == &lfs.gc.o.o);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfsr_unmount(&lfs) => 0;
|
||||||
@@ -1404,17 +1398,16 @@ code = '''
|
|||||||
// running lfsr_fs_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
|
||||||
while (true) {
|
for (lfs_block_t i = 0;; i++) {
|
||||||
int err = lfsr_fs_gc(&lfs, LFS_GC_CKDATA);
|
// a bit hacky, but this catches infinite loops
|
||||||
|
LFS_ASSERT(i < 2*BLOCK_COUNT);
|
||||||
|
|
||||||
|
int err = lfsr_fs_gc(&lfs, GC_STEPS, LFS_GC_CKDATA);
|
||||||
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) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we should find the clobbered block before finishing the
|
|
||||||
// traversal
|
|
||||||
assert(lfs.omdirs == &lfs.gc.o.o);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfsr_unmount(&lfs) => 0;
|
||||||
@@ -1603,7 +1596,7 @@ done:;
|
|||||||
# pseudo-fuzz test that dirtying still works with the GC API
|
# pseudo-fuzz test that dirtying still works with the GC API
|
||||||
[cases.test_gc_mutation]
|
[cases.test_gc_mutation]
|
||||||
defines.GC_STEPS = [-1, 1, 2, 10, 100, 1000]
|
defines.GC_STEPS = [-1, 1, 2, 10, 100, 1000]
|
||||||
defines.STEPS = 100
|
defines.N = 100
|
||||||
defines.MKCONSISTENT = [false, true]
|
defines.MKCONSISTENT = [false, true]
|
||||||
defines.LOOKAHEAD = [false, true]
|
defines.LOOKAHEAD = [false, true]
|
||||||
defines.COMPACT = [false, true]
|
defines.COMPACT = [false, true]
|
||||||
@@ -1637,7 +1630,7 @@ code = '''
|
|||||||
lfsr_file_write(&lfs, &file, wbuf, SIZE) => SIZE;
|
lfsr_file_write(&lfs, &file, wbuf, SIZE) => SIZE;
|
||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < STEPS; i++) {
|
for (uint32_t i = 0; i < N; i++) {
|
||||||
// rewrite the file every gc cycle
|
// rewrite the file every gc cycle
|
||||||
lfsr_file_open(&lfs, &file, "spider",
|
lfsr_file_open(&lfs, &file, "spider",
|
||||||
LFS_O_WRONLY | LFS_O_TRUNC) => 0;
|
LFS_O_WRONLY | LFS_O_TRUNC) => 0;
|
||||||
@@ -1648,7 +1641,7 @@ code = '''
|
|||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
// gc!
|
// gc!
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
((MKCONSISTENT) ? LFS_GC_MKCONSISTENT : 0)
|
((MKCONSISTENT) ? LFS_GC_MKCONSISTENT : 0)
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
||||||
@@ -1669,7 +1662,7 @@ code = '''
|
|||||||
# pseudo-fuzz test that adding/removing flags doesn't break anything
|
# pseudo-fuzz test that adding/removing flags doesn't break anything
|
||||||
[cases.test_gc_changing_flags]
|
[cases.test_gc_changing_flags]
|
||||||
defines.GC_STEPS = [-1, 1, 2, 10, 100, 1000]
|
defines.GC_STEPS = [-1, 1, 2, 10, 100, 1000]
|
||||||
defines.STEPS = 100
|
defines.N = 100
|
||||||
defines.MKCONSISTENT = [false, true]
|
defines.MKCONSISTENT = [false, true]
|
||||||
defines.LOOKAHEAD = [false, true]
|
defines.LOOKAHEAD = [false, true]
|
||||||
defines.COMPACT = [false, true]
|
defines.COMPACT = [false, true]
|
||||||
@@ -1703,7 +1696,7 @@ code = '''
|
|||||||
lfsr_file_write(&lfs, &file, wbuf, SIZE) => SIZE;
|
lfsr_file_write(&lfs, &file, wbuf, SIZE) => SIZE;
|
||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < STEPS; i++) {
|
for (uint32_t i = 0; i < N; i++) {
|
||||||
// rewrite the file every gc cycle
|
// rewrite the file every gc cycle
|
||||||
lfsr_file_open(&lfs, &file, "spider",
|
lfsr_file_open(&lfs, &file, "spider",
|
||||||
LFS_O_WRONLY | LFS_O_TRUNC) => 0;
|
LFS_O_WRONLY | LFS_O_TRUNC) => 0;
|
||||||
@@ -1723,7 +1716,7 @@ code = '''
|
|||||||
) & TEST_PRNG(&prng);
|
) & TEST_PRNG(&prng);
|
||||||
|
|
||||||
// gc!
|
// gc!
|
||||||
lfsr_fs_gc(&lfs, flags) => 0;
|
lfsr_fs_gc(&lfs, GC_STEPS, flags) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the file contents
|
// check the file contents
|
||||||
@@ -1765,7 +1758,7 @@ code = '''
|
|||||||
assert(!err || (TEST_PLS && err == LFS_ERR_EXIST));
|
assert(!err || (TEST_PLS && err == LFS_ERR_EXIST));
|
||||||
|
|
||||||
// gc!
|
// gc!
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
((MKCONSISTENT) ? LFS_GC_MKCONSISTENT : 0)
|
((MKCONSISTENT) ? LFS_GC_MKCONSISTENT : 0)
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
||||||
@@ -1943,7 +1936,7 @@ code = '''
|
|||||||
}
|
}
|
||||||
|
|
||||||
// gc!
|
// gc!
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
((MKCONSISTENT) ? LFS_GC_MKCONSISTENT : 0)
|
((MKCONSISTENT) ? LFS_GC_MKCONSISTENT : 0)
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
||||||
@@ -2046,7 +2039,7 @@ code = '''
|
|||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
// gc!
|
// gc!
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
((MKCONSISTENT) ? LFS_GC_MKCONSISTENT : 0)
|
((MKCONSISTENT) ? LFS_GC_MKCONSISTENT : 0)
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
||||||
@@ -2245,7 +2238,7 @@ code = '''
|
|||||||
}
|
}
|
||||||
|
|
||||||
// gc!
|
// gc!
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
((MKCONSISTENT) ? LFS_GC_MKCONSISTENT : 0)
|
((MKCONSISTENT) ? LFS_GC_MKCONSISTENT : 0)
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
||||||
@@ -2409,7 +2402,7 @@ code = '''
|
|||||||
}
|
}
|
||||||
|
|
||||||
// gc!
|
// gc!
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
((MKCONSISTENT) ? LFS_GC_MKCONSISTENT : 0)
|
((MKCONSISTENT) ? LFS_GC_MKCONSISTENT : 0)
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
||||||
@@ -2739,7 +2732,7 @@ code = '''
|
|||||||
}
|
}
|
||||||
|
|
||||||
// gc!
|
// gc!
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
((MKCONSISTENT) ? LFS_GC_MKCONSISTENT : 0)
|
((MKCONSISTENT) ? LFS_GC_MKCONSISTENT : 0)
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
||||||
@@ -3157,7 +3150,7 @@ code = '''
|
|||||||
}
|
}
|
||||||
|
|
||||||
// gc!
|
// gc!
|
||||||
lfsr_fs_gc(&lfs,
|
lfsr_fs_gc(&lfs, GC_STEPS,
|
||||||
((MKCONSISTENT) ? LFS_GC_MKCONSISTENT : 0)
|
((MKCONSISTENT) ? LFS_GC_MKCONSISTENT : 0)
|
||||||
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
| ((LOOKAHEAD) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
| ((COMPACT) ? LFS_GC_COMPACT : 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user