diff --git a/lfs.c b/lfs.c index aed9a602..979121a1 100644 --- a/lfs.c +++ b/lfs.c @@ -15286,9 +15286,6 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { // // wear-leveling. // LFS_ASSERT(lfs->cfg->block_cycles != 0); - // block_recycles should not be zero, use -1 to disable - LFS_ASSERT(lfs->cfg->block_recycles != 0); - // inline_size must be <= block_size/4 LFS_ASSERT(lfs->cfg->inline_size <= lfs->cfg->block_size/4); // shrub_size must be <= block_size/4 @@ -15375,12 +15372,13 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { // find the number of bits to use for recycle counters // - // Multiply by 2, since we alternate which metadata block we erase each - // compaction, and limit to 28-bits so we always have some bits to - // determine the most recent revision. + // Add 1, to include the initial erase, multiply by 2, since we + // alternate which metadata block we erase each compaction, and limit + // to 28-bits so we always have some bits to determine the most recent + // revision. if (lfs->cfg->block_recycles != -1) { lfs->recycle_bits = lfs_min( - lfs_nlog2(2*lfs->cfg->block_recycles+1)-1, + lfs_nlog2(2*(lfs->cfg->block_recycles+1)+1)-1, 28); } else { lfs->recycle_bits = -1; diff --git a/lfs.h b/lfs.h index c974e09e..3fc57460 100644 --- a/lfs.h +++ b/lfs.h @@ -209,9 +209,11 @@ struct lfs_config { // Number of erase cycles before metadata blocks are relocated for // wear-leveling. Suggested values are in the range 16-1024. Larger values // relocate less frequently, improving average performance, at the cost - // of worse wear distribution. Note this is rounded down to a power-of-2. + // of worse wear distribution. Note this ends up rounded down to a + // power-of-2. // - // Set to -1 to disable block-level wear-leveling. + // 0 results in pure copy-on-write, which may be counter-productive. Set + // to -1 to disable block-level wear-leveling. int32_t block_recycles; // Size of the read cache in bytes. Larger buffers can improve diff --git a/tests/test_mtree.toml b/tests/test_mtree.toml index aa041c2b..6044aaf1 100644 --- a/tests/test_mtree.toml +++ b/tests/test_mtree.toml @@ -1136,7 +1136,7 @@ code = ''' # this should be set so only one entry can fit in a metadata block defines.SIZE = 'BLOCK_SIZE / 4' # make it so blocks relocate every two compacts -defines.BLOCK_RECYCLES = 1 +defines.BLOCK_RECYCLES = 0 in = 'lfs.c' code = ''' lfs_t lfs; @@ -1221,7 +1221,7 @@ code = ''' # this should be set so only one entry can fit in a metadata block defines.SIZE = 'BLOCK_SIZE / 4' # make it so blocks relocate every two compacts -defines.BLOCK_RECYCLES = 1 +defines.BLOCK_RECYCLES = 0 in = 'lfs.c' code = ''' lfs_t lfs; @@ -1318,7 +1318,7 @@ code = ''' # this should be set so only one entry can fit in a metadata block defines.SIZE = 'BLOCK_SIZE / 4' # make it so blocks relocate every two compacts -defines.BLOCK_RECYCLES = 1 +defines.BLOCK_RECYCLES = 0 in = 'lfs.c' code = ''' lfs_t lfs; @@ -1415,7 +1415,7 @@ code = ''' # this should be set so only one entry can fit in a metadata block defines.SIZE = 'BLOCK_SIZE / 4' # make it so blocks relocate every two compacts -defines.BLOCK_RECYCLES = 1 +defines.BLOCK_RECYCLES = 0 in = 'lfs.c' code = ''' lfs_t lfs; @@ -1469,7 +1469,7 @@ code = ''' # this should be set so only one entry can fit in a metadata block defines.SIZE = 'BLOCK_SIZE / 4' # make it so blocks relocate every two compacts -defines.BLOCK_RECYCLES = 1 +defines.BLOCK_RECYCLES = 0 # force our block to compact by setting prog_size=block_size, we don't have # an easy way to force the intermediary mroots to compact otherwise defines.PROG_SIZE = 'BLOCK_SIZE' @@ -1540,7 +1540,7 @@ code = ''' # this should be set so only one entry can fit in a metadata block defines.SIZE = 'BLOCK_SIZE / 4' # make it so blocks relocate every two compacts -defines.BLOCK_RECYCLES = 1 +defines.BLOCK_RECYCLES = 0 in = 'lfs.c' code = ''' lfs_t lfs; @@ -1603,7 +1603,7 @@ code = ''' # this should be set so only one entry can fit in a metadata block defines.SIZE = 'BLOCK_SIZE / 4' # make it so blocks relocate every two compacts -defines.BLOCK_RECYCLES = 1 +defines.BLOCK_RECYCLES = 0 in = 'lfs.c' code = ''' lfs_t lfs; @@ -1705,7 +1705,7 @@ code = ''' # this should be set so only one entry can fit in a metadata block defines.SIZE = 'BLOCK_SIZE / 4' # make it so blocks relocate every two compacts -defines.BLOCK_RECYCLES = 1 +defines.BLOCK_RECYCLES = 0 in = 'lfs.c' code = ''' lfs_t lfs; @@ -1824,7 +1824,7 @@ code = ''' # this should be set so only one entry can fit in a metadata block defines.SIZE = 'BLOCK_SIZE / 4' # make it so blocks relocate every two compacts -defines.BLOCK_RECYCLES = 1 +defines.BLOCK_RECYCLES = 0 in = 'lfs.c' code = ''' lfs_t lfs; @@ -1914,7 +1914,7 @@ code = ''' # this should be set so only one entry can fit in a metadata block defines.SIZE = 'BLOCK_SIZE / 4' # make it so blocks relocate every two compacts -defines.BLOCK_RECYCLES = 1 +defines.BLOCK_RECYCLES = 0 in = 'lfs.c' code = ''' lfs_t lfs; @@ -1990,7 +1990,7 @@ code = ''' # this should be set so only one entry can fit in a metadata block defines.SIZE = 'BLOCK_SIZE / 4' # make it so blocks relocate every two compacts -defines.BLOCK_RECYCLES = 1 +defines.BLOCK_RECYCLES = 0 in = 'lfs.c' code = ''' lfs_t lfs; @@ -2076,7 +2076,7 @@ code = ''' [cases.test_mtree_relocate_fuzz] defines.N = [5, 10, 20, 40] defines.FORCE_COMPACTION = [false, true] -defines.BLOCK_RECYCLES = [5, 2, 1] +defines.BLOCK_RECYCLES = [5, 1, 0] defines.SEED = 'range(500)' in = 'lfs.c' code = ''' @@ -2555,7 +2555,7 @@ code = ''' [cases.test_mtree_opened_extend] # make it so blocks relocate every two compacts -defines.BLOCK_RECYCLES = 1 +defines.BLOCK_RECYCLES = 0 in = 'lfs.c' code = ''' lfs_t lfs; @@ -2613,7 +2613,7 @@ code = ''' # this should be set so only one entry can fit in a metadata block defines.SIZE = 'BLOCK_SIZE / 4' # make it so blocks relocate every two compacts -defines.BLOCK_RECYCLES = 1 +defines.BLOCK_RECYCLES = 0 in = 'lfs.c' code = ''' lfs_t lfs; @@ -2702,7 +2702,7 @@ code = ''' # this should be set so only one entry can fit in a metadata block defines.SIZE = 'BLOCK_SIZE / 4' # make it so blocks relocate every two compacts -defines.BLOCK_RECYCLES = 1 +defines.BLOCK_RECYCLES = 0 in = 'lfs.c' code = ''' lfs_t lfs; @@ -3528,7 +3528,7 @@ code = ''' [cases.test_mtree_traversal_extend] defines.VALIDATE = [false, true] # make it so blocks relocate every two compacts -defines.BLOCK_RECYCLES = 1 +defines.BLOCK_RECYCLES = 0 in = 'lfs.c' code = ''' lfs_t lfs; @@ -4003,7 +4003,7 @@ code = ''' # this should be set so only one entry can fit in a metadata block defines.SIZE = 'BLOCK_SIZE / 4' # make it so blocks relocate every two compacts -defines.BLOCK_RECYCLES = 1 +defines.BLOCK_RECYCLES = 0 in = 'lfs.c' code = ''' lfs_t lfs; @@ -4057,7 +4057,7 @@ code = ''' # this should be set so only one entry can fit in a metadata block defines.SIZE = 'BLOCK_SIZE / 4' # make it so blocks relocate every two compacts -defines.BLOCK_RECYCLES = 1 +defines.BLOCK_RECYCLES = 0 # force our block to compact by setting prog_size=block_size, we don't have # any way to indirectly force the intermediary mroots to compact otherwise defines.PROG_SIZE = 'BLOCK_SIZE' diff --git a/tests/test_wl.toml b/tests/test_wl.toml index 0e9ac9c6..398df132 100644 --- a/tests/test_wl.toml +++ b/tests/test_wl.toml @@ -15,7 +15,7 @@ after = [ # dirs + relocations may create problems for gstate [cases.test_wl_dir_fuzz] -defines.BLOCK_RECYCLES = [-1, 8, 2, 1] +defines.BLOCK_RECYCLES = [-1, 5, 1, 0] defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512] defines.OPS = 1024 defines.REMOUNT = [false, true] @@ -163,7 +163,7 @@ code = ''' # files + relocations may create problems for shrubs [cases.test_wl_file_fuzz] -defines.BLOCK_RECYCLES = [-1, 8, 2, 1] +defines.BLOCK_RECYCLES = [-1, 5, 1, 0] defines.N = [1, 2, 4, 8, 16, 32, 64] defines.OPS = 1024 defines.SIZE = [ @@ -374,7 +374,7 @@ code = ''' # open files + relocations may create problems for orphans/zombies [cases.test_wl_orphanzombie_fuzz] -defines.BLOCK_RECYCLES = [-1, 8, 2, 1] +defines.BLOCK_RECYCLES = [-1, 5, 1, 0] defines.N = [1, 2, 4, 8, 16, 32, 64] defines.OPS = 1024 defines.SIZE = [ @@ -713,7 +713,7 @@ code = ''' # open files + dirs + relocations can cause so many problems it's not worth # listing them [cases.test_wl_orphanzombiedir_fuzz] -defines.BLOCK_RECYCLES = [-1, 8, 2, 1] +defines.BLOCK_RECYCLES = [-1, 5, 1, 0] defines.N = [1, 2, 4, 8, 16, 32, 64] defines.OPS = 1024 defines.SIZE = [