Shifted block_recycles so 0 => pure copy-on-write
This makes a bit more sense with the new block_recycles name. block_recycles=0 (previously block_recycles=1) requires 1 erase, but it doesn't really "recycle" the block. With this change, block_recycles=1 "recycles" the block once (2 erases in total) before relocating, which I think is a bit more intuitive. Note, this sort of messes with our power-of-2 rounding, as the block_recycles is technically rounded down to the nearest power-of-2 after adding 1: - block_recycles=1022 -> 512 erases - block_recycles=1023 -> 1024 erases - block_recycles=1024 -> 1024 erases - block_recycles=1025 -> 1024 erases But I'm going to keep the block_recycles description more-or-less as is for now, as I think this extra detail is more confusing than useful, powers-of-2 stay powers-of-2, and the <=block_recycles contraint is not violated.
This commit is contained in:
@@ -15286,9 +15286,6 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
// // wear-leveling.
|
// // wear-leveling.
|
||||||
// LFS_ASSERT(lfs->cfg->block_cycles != 0);
|
// 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
|
// inline_size must be <= block_size/4
|
||||||
LFS_ASSERT(lfs->cfg->inline_size <= lfs->cfg->block_size/4);
|
LFS_ASSERT(lfs->cfg->inline_size <= lfs->cfg->block_size/4);
|
||||||
// shrub_size must be <= 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
|
// find the number of bits to use for recycle counters
|
||||||
//
|
//
|
||||||
// Multiply by 2, since we alternate which metadata block we erase each
|
// Add 1, to include the initial erase, multiply by 2, since we
|
||||||
// compaction, and limit to 28-bits so we always have some bits to
|
// alternate which metadata block we erase each compaction, and limit
|
||||||
// determine the most recent revision.
|
// to 28-bits so we always have some bits to determine the most recent
|
||||||
|
// revision.
|
||||||
if (lfs->cfg->block_recycles != -1) {
|
if (lfs->cfg->block_recycles != -1) {
|
||||||
lfs->recycle_bits = lfs_min(
|
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);
|
28);
|
||||||
} else {
|
} else {
|
||||||
lfs->recycle_bits = -1;
|
lfs->recycle_bits = -1;
|
||||||
|
|||||||
@@ -209,9 +209,11 @@ struct lfs_config {
|
|||||||
// Number of erase cycles before metadata blocks are relocated for
|
// Number of erase cycles before metadata blocks are relocated for
|
||||||
// wear-leveling. Suggested values are in the range 16-1024. Larger values
|
// wear-leveling. Suggested values are in the range 16-1024. Larger values
|
||||||
// relocate less frequently, improving average performance, at the cost
|
// 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;
|
int32_t block_recycles;
|
||||||
|
|
||||||
// Size of the read cache in bytes. Larger buffers can improve
|
// Size of the read cache in bytes. Larger buffers can improve
|
||||||
|
|||||||
+18
-18
@@ -1136,7 +1136,7 @@ code = '''
|
|||||||
# this should be set so only one entry can fit in a metadata block
|
# this should be set so only one entry can fit in a metadata block
|
||||||
defines.SIZE = 'BLOCK_SIZE / 4'
|
defines.SIZE = 'BLOCK_SIZE / 4'
|
||||||
# make it so blocks relocate every two compacts
|
# make it so blocks relocate every two compacts
|
||||||
defines.BLOCK_RECYCLES = 1
|
defines.BLOCK_RECYCLES = 0
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -1221,7 +1221,7 @@ code = '''
|
|||||||
# this should be set so only one entry can fit in a metadata block
|
# this should be set so only one entry can fit in a metadata block
|
||||||
defines.SIZE = 'BLOCK_SIZE / 4'
|
defines.SIZE = 'BLOCK_SIZE / 4'
|
||||||
# make it so blocks relocate every two compacts
|
# make it so blocks relocate every two compacts
|
||||||
defines.BLOCK_RECYCLES = 1
|
defines.BLOCK_RECYCLES = 0
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -1318,7 +1318,7 @@ code = '''
|
|||||||
# this should be set so only one entry can fit in a metadata block
|
# this should be set so only one entry can fit in a metadata block
|
||||||
defines.SIZE = 'BLOCK_SIZE / 4'
|
defines.SIZE = 'BLOCK_SIZE / 4'
|
||||||
# make it so blocks relocate every two compacts
|
# make it so blocks relocate every two compacts
|
||||||
defines.BLOCK_RECYCLES = 1
|
defines.BLOCK_RECYCLES = 0
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -1415,7 +1415,7 @@ code = '''
|
|||||||
# this should be set so only one entry can fit in a metadata block
|
# this should be set so only one entry can fit in a metadata block
|
||||||
defines.SIZE = 'BLOCK_SIZE / 4'
|
defines.SIZE = 'BLOCK_SIZE / 4'
|
||||||
# make it so blocks relocate every two compacts
|
# make it so blocks relocate every two compacts
|
||||||
defines.BLOCK_RECYCLES = 1
|
defines.BLOCK_RECYCLES = 0
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -1469,7 +1469,7 @@ code = '''
|
|||||||
# this should be set so only one entry can fit in a metadata block
|
# this should be set so only one entry can fit in a metadata block
|
||||||
defines.SIZE = 'BLOCK_SIZE / 4'
|
defines.SIZE = 'BLOCK_SIZE / 4'
|
||||||
# make it so blocks relocate every two compacts
|
# 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
|
# 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
|
# an easy way to force the intermediary mroots to compact otherwise
|
||||||
defines.PROG_SIZE = 'BLOCK_SIZE'
|
defines.PROG_SIZE = 'BLOCK_SIZE'
|
||||||
@@ -1540,7 +1540,7 @@ code = '''
|
|||||||
# this should be set so only one entry can fit in a metadata block
|
# this should be set so only one entry can fit in a metadata block
|
||||||
defines.SIZE = 'BLOCK_SIZE / 4'
|
defines.SIZE = 'BLOCK_SIZE / 4'
|
||||||
# make it so blocks relocate every two compacts
|
# make it so blocks relocate every two compacts
|
||||||
defines.BLOCK_RECYCLES = 1
|
defines.BLOCK_RECYCLES = 0
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -1603,7 +1603,7 @@ code = '''
|
|||||||
# this should be set so only one entry can fit in a metadata block
|
# this should be set so only one entry can fit in a metadata block
|
||||||
defines.SIZE = 'BLOCK_SIZE / 4'
|
defines.SIZE = 'BLOCK_SIZE / 4'
|
||||||
# make it so blocks relocate every two compacts
|
# make it so blocks relocate every two compacts
|
||||||
defines.BLOCK_RECYCLES = 1
|
defines.BLOCK_RECYCLES = 0
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -1705,7 +1705,7 @@ code = '''
|
|||||||
# this should be set so only one entry can fit in a metadata block
|
# this should be set so only one entry can fit in a metadata block
|
||||||
defines.SIZE = 'BLOCK_SIZE / 4'
|
defines.SIZE = 'BLOCK_SIZE / 4'
|
||||||
# make it so blocks relocate every two compacts
|
# make it so blocks relocate every two compacts
|
||||||
defines.BLOCK_RECYCLES = 1
|
defines.BLOCK_RECYCLES = 0
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -1824,7 +1824,7 @@ code = '''
|
|||||||
# this should be set so only one entry can fit in a metadata block
|
# this should be set so only one entry can fit in a metadata block
|
||||||
defines.SIZE = 'BLOCK_SIZE / 4'
|
defines.SIZE = 'BLOCK_SIZE / 4'
|
||||||
# make it so blocks relocate every two compacts
|
# make it so blocks relocate every two compacts
|
||||||
defines.BLOCK_RECYCLES = 1
|
defines.BLOCK_RECYCLES = 0
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -1914,7 +1914,7 @@ code = '''
|
|||||||
# this should be set so only one entry can fit in a metadata block
|
# this should be set so only one entry can fit in a metadata block
|
||||||
defines.SIZE = 'BLOCK_SIZE / 4'
|
defines.SIZE = 'BLOCK_SIZE / 4'
|
||||||
# make it so blocks relocate every two compacts
|
# make it so blocks relocate every two compacts
|
||||||
defines.BLOCK_RECYCLES = 1
|
defines.BLOCK_RECYCLES = 0
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -1990,7 +1990,7 @@ code = '''
|
|||||||
# this should be set so only one entry can fit in a metadata block
|
# this should be set so only one entry can fit in a metadata block
|
||||||
defines.SIZE = 'BLOCK_SIZE / 4'
|
defines.SIZE = 'BLOCK_SIZE / 4'
|
||||||
# make it so blocks relocate every two compacts
|
# make it so blocks relocate every two compacts
|
||||||
defines.BLOCK_RECYCLES = 1
|
defines.BLOCK_RECYCLES = 0
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -2076,7 +2076,7 @@ code = '''
|
|||||||
[cases.test_mtree_relocate_fuzz]
|
[cases.test_mtree_relocate_fuzz]
|
||||||
defines.N = [5, 10, 20, 40]
|
defines.N = [5, 10, 20, 40]
|
||||||
defines.FORCE_COMPACTION = [false, true]
|
defines.FORCE_COMPACTION = [false, true]
|
||||||
defines.BLOCK_RECYCLES = [5, 2, 1]
|
defines.BLOCK_RECYCLES = [5, 1, 0]
|
||||||
defines.SEED = 'range(500)'
|
defines.SEED = 'range(500)'
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
@@ -2555,7 +2555,7 @@ code = '''
|
|||||||
|
|
||||||
[cases.test_mtree_opened_extend]
|
[cases.test_mtree_opened_extend]
|
||||||
# make it so blocks relocate every two compacts
|
# make it so blocks relocate every two compacts
|
||||||
defines.BLOCK_RECYCLES = 1
|
defines.BLOCK_RECYCLES = 0
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -2613,7 +2613,7 @@ code = '''
|
|||||||
# this should be set so only one entry can fit in a metadata block
|
# this should be set so only one entry can fit in a metadata block
|
||||||
defines.SIZE = 'BLOCK_SIZE / 4'
|
defines.SIZE = 'BLOCK_SIZE / 4'
|
||||||
# make it so blocks relocate every two compacts
|
# make it so blocks relocate every two compacts
|
||||||
defines.BLOCK_RECYCLES = 1
|
defines.BLOCK_RECYCLES = 0
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -2702,7 +2702,7 @@ code = '''
|
|||||||
# this should be set so only one entry can fit in a metadata block
|
# this should be set so only one entry can fit in a metadata block
|
||||||
defines.SIZE = 'BLOCK_SIZE / 4'
|
defines.SIZE = 'BLOCK_SIZE / 4'
|
||||||
# make it so blocks relocate every two compacts
|
# make it so blocks relocate every two compacts
|
||||||
defines.BLOCK_RECYCLES = 1
|
defines.BLOCK_RECYCLES = 0
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -3528,7 +3528,7 @@ code = '''
|
|||||||
[cases.test_mtree_traversal_extend]
|
[cases.test_mtree_traversal_extend]
|
||||||
defines.VALIDATE = [false, true]
|
defines.VALIDATE = [false, true]
|
||||||
# make it so blocks relocate every two compacts
|
# make it so blocks relocate every two compacts
|
||||||
defines.BLOCK_RECYCLES = 1
|
defines.BLOCK_RECYCLES = 0
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -4003,7 +4003,7 @@ code = '''
|
|||||||
# this should be set so only one entry can fit in a metadata block
|
# this should be set so only one entry can fit in a metadata block
|
||||||
defines.SIZE = 'BLOCK_SIZE / 4'
|
defines.SIZE = 'BLOCK_SIZE / 4'
|
||||||
# make it so blocks relocate every two compacts
|
# make it so blocks relocate every two compacts
|
||||||
defines.BLOCK_RECYCLES = 1
|
defines.BLOCK_RECYCLES = 0
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -4057,7 +4057,7 @@ code = '''
|
|||||||
# this should be set so only one entry can fit in a metadata block
|
# this should be set so only one entry can fit in a metadata block
|
||||||
defines.SIZE = 'BLOCK_SIZE / 4'
|
defines.SIZE = 'BLOCK_SIZE / 4'
|
||||||
# make it so blocks relocate every two compacts
|
# 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
|
# 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
|
# any way to indirectly force the intermediary mroots to compact otherwise
|
||||||
defines.PROG_SIZE = 'BLOCK_SIZE'
|
defines.PROG_SIZE = 'BLOCK_SIZE'
|
||||||
|
|||||||
+4
-4
@@ -15,7 +15,7 @@ after = [
|
|||||||
|
|
||||||
# dirs + relocations may create problems for gstate
|
# dirs + relocations may create problems for gstate
|
||||||
[cases.test_wl_dir_fuzz]
|
[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.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
||||||
defines.OPS = 1024
|
defines.OPS = 1024
|
||||||
defines.REMOUNT = [false, true]
|
defines.REMOUNT = [false, true]
|
||||||
@@ -163,7 +163,7 @@ code = '''
|
|||||||
|
|
||||||
# files + relocations may create problems for shrubs
|
# files + relocations may create problems for shrubs
|
||||||
[cases.test_wl_file_fuzz]
|
[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.N = [1, 2, 4, 8, 16, 32, 64]
|
||||||
defines.OPS = 1024
|
defines.OPS = 1024
|
||||||
defines.SIZE = [
|
defines.SIZE = [
|
||||||
@@ -374,7 +374,7 @@ code = '''
|
|||||||
|
|
||||||
# open files + relocations may create problems for orphans/zombies
|
# open files + relocations may create problems for orphans/zombies
|
||||||
[cases.test_wl_orphanzombie_fuzz]
|
[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.N = [1, 2, 4, 8, 16, 32, 64]
|
||||||
defines.OPS = 1024
|
defines.OPS = 1024
|
||||||
defines.SIZE = [
|
defines.SIZE = [
|
||||||
@@ -713,7 +713,7 @@ code = '''
|
|||||||
# open files + dirs + relocations can cause so many problems it's not worth
|
# open files + dirs + relocations can cause so many problems it's not worth
|
||||||
# listing them
|
# listing them
|
||||||
[cases.test_wl_orphanzombiedir_fuzz]
|
[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.N = [1, 2, 4, 8, 16, 32, 64]
|
||||||
defines.OPS = 1024
|
defines.OPS = 1024
|
||||||
defines.SIZE = [
|
defines.SIZE = [
|
||||||
|
|||||||
Reference in New Issue
Block a user