diff --git a/lfs.c b/lfs.c index 70cf576a..6248cbb3 100644 --- a/lfs.c +++ b/lfs.c @@ -13069,29 +13069,33 @@ int lfsr_fs_gc(lfs_t *lfs, lfs_soff_t steps, uint32_t flags) { if (!lfsr_omdir_isopen(lfs, &lfs->gc.o.o)) { lfs->gc = LFSR_TRAVERSAL(pending); lfsr_omdir_open(lfs, &lfs->gc.o.o); + } - // existing traversal? - } else { - // mask flags, we can't trust existing traversals to make - // progress if flags change - lfs->gc.o.o.flags &= ~( + // mask flags, we can't trust existing traversals to make + // progress if flags change + lfs->gc.o.o.flags &= ( + pending | ~( LFS_GC_MKCONSISTENT | LFS_GC_LOOKAHEAD | LFS_GC_COMPACT | LFS_GC_CKMETA - | LFS_GC_CKDATA - ) | pending; + | LFS_GC_CKDATA)); - // will this traversal still make progress? no? start over - if (!(lfs->gc.o.o.flags & ( - LFS_GC_MKCONSISTENT - | LFS_GC_LOOKAHEAD - | LFS_GC_COMPACT - | LFS_GC_CKMETA - | LFS_GC_CKDATA))) { - lfsr_omdir_close(lfs, &lfs->gc.o.o); - continue; - } + // don't bother with lookahead if we've mutated + if (lfsr_f_isdirty(lfs->gc.o.o.flags) + || lfsr_f_ismutated(lfs->gc.o.o.flags)) { + lfs->gc.o.o.flags &= ~LFS_GC_LOOKAHEAD; + } + + // will this traversal still make progress? no? start over + if (!(lfs->gc.o.o.flags & ( + LFS_GC_MKCONSISTENT + | LFS_GC_LOOKAHEAD + | LFS_GC_COMPACT + | LFS_GC_CKMETA + | LFS_GC_CKDATA))) { + lfsr_omdir_close(lfs, &lfs->gc.o.o); + continue; } // do we really need a full traversal? diff --git a/tests/test_gc.toml b/tests/test_gc.toml index 8e6270bf..391131c1 100644 --- a/tests/test_gc.toml +++ b/tests/test_gc.toml @@ -80,6 +80,8 @@ defines.SIZE = [ '2*BLOCK_SIZE', '8*BLOCK_SIZE', ] +# we need something to keep the traversal running +if = 'CKMETA || CKDATA' code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -378,6 +380,8 @@ defines.SIZE = [ ] # set compact thresh to minimum defines.GC_COMPACT_THRESH = 'BLOCK_SIZE/2' +# we need something to keep the traversal running +if = 'CKMETA || CKDATA' code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -878,6 +882,8 @@ defines.SIZE = 'FILE_BUFFER_SIZE/2' # <=2 => grm-able # >2 => requires orphans defines.ORPHANS = [3, 100] +# we need something to keep the traversal running +if = 'CKMETA || CKDATA' code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0;