From 53a6e0471215b680426f97d9afce241d739ee49d Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Wed, 17 Jul 2019 17:05:20 -0500 Subject: [PATCH 1/3] Changed block_cycles disable from 0 to -1 As it is now, block_cycles = 0 disables wear leveling. This was a mistake as 0 is the "default" value for several other config options. It's even worse when migrating from v1 as it's easy to miss the addition of block_cycles and end up with a filesystem that is not actually wear-leveling. Clearly, block_cycles = 0 should do anything but disable wear-leveling. Here, I've changed block_cycles = 0 to assert. Forcing users to set a value for block_cycles (500 is suggested). block_cycles can be set to -1 to explicitly disable wear leveling if desired. --- lfs.c | 8 +++++--- lfs.h | 9 ++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lfs.c b/lfs.c index c554135..0417202 100644 --- a/lfs.c +++ b/lfs.c @@ -1453,7 +1453,7 @@ static int lfs_dir_compact(lfs_t *lfs, // increment revision count dir->rev += 1; - if (lfs->cfg->block_cycles && + if (lfs->cfg->block_cycles > 0 && (dir->rev % (lfs->cfg->block_cycles+1) == 0)) { if (lfs_pair_cmp(dir->pair, (const lfs_block_t[2]){0, 1}) == 0) { // oh no! we're writing too much to the superblock, @@ -3192,8 +3192,10 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { LFS_ASSERT(4*lfs_npw2(0xffffffff / (lfs->cfg->block_size-2*4)) <= lfs->cfg->block_size); - // we don't support some corner cases - LFS_ASSERT(lfs->cfg->block_cycles < 0xffffffff); + // block_cycles = 0 is no longer supported, must either set a number + // of erase cycles before moving logs to another block (~500 suggested), + // or explicitly disable wear-leveling with -1. + LFS_ASSERT(lfs->cfg->block_cycles != 0); // setup read cache if (lfs->cfg->read_buffer) { diff --git a/lfs.h b/lfs.h index c78b3d6..276b5a5 100644 --- a/lfs.h +++ b/lfs.h @@ -190,9 +190,12 @@ struct lfs_config { // Number of erasable blocks on the device. lfs_size_t block_count; - // Number of erase cycles before we should move data to another block. - // May be zero, in which case no block-level wear-leveling is performed. - uint32_t block_cycles; + // Number of erase cycles before we should move logs to another block. + // Suggested values are in the range 100-1000, with large values having + // better performance at the cost of less consistent wear distribution. + // + // Set to -1 to disable block-level wear-leveling. + int32_t block_cycles; // Size of block caches. Each cache buffers a portion of a block in RAM. // The littlefs needs a read cache, a program cache, and one additional From 38a2a8d2a3d64e5219ec0babaf233ae9e8da577c Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sun, 28 Jul 2019 20:42:13 -0500 Subject: [PATCH 2/3] Minor improvement to documentation over block_cycles Suggested by haneefmubarak --- lfs.c | 10 +++++++--- lfs.h | 7 ++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lfs.c b/lfs.c index 0417202..3fe6389 100644 --- a/lfs.c +++ b/lfs.c @@ -3192,11 +3192,15 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { LFS_ASSERT(4*lfs_npw2(0xffffffff / (lfs->cfg->block_size-2*4)) <= lfs->cfg->block_size); - // block_cycles = 0 is no longer supported, must either set a number - // of erase cycles before moving logs to another block (~500 suggested), - // or explicitly disable wear-leveling with -1. + // block_cycles = 0 is no longer supported. + // + // block_cycles is the number of erase cycles before littlefs evicts + // metadata logs as a part of wear leveling. Suggested values are in the + // range of 100-1000, or set block_cycles to -1 to disable block-level + // wear-leveling. LFS_ASSERT(lfs->cfg->block_cycles != 0); + // setup read cache if (lfs->cfg->read_buffer) { lfs->rcache.buffer = lfs->cfg->read_buffer; diff --git a/lfs.h b/lfs.h index 276b5a5..6abfcdb 100644 --- a/lfs.h +++ b/lfs.h @@ -190,9 +190,10 @@ struct lfs_config { // Number of erasable blocks on the device. lfs_size_t block_count; - // Number of erase cycles before we should move logs to another block. - // Suggested values are in the range 100-1000, with large values having - // better performance at the cost of less consistent wear distribution. + // Number of erase cycles before littlefs evicts metadata logs and moves + // the metadata to another block. Suggested values are in the + // range 100-1000, with large values having better performance at the cost + // of less consistent wear distribution. // // Set to -1 to disable block-level wear-leveling. int32_t block_cycles; From e8c023aab055a8892b8abc262d82f78a11108dc5 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sun, 28 Jul 2019 20:43:12 -0500 Subject: [PATCH 3/3] Changed FUSE branch to v2 (previously v2-alpha) --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index dcfedf6..ab69041 100644 --- a/.travis.yml +++ b/.travis.yml @@ -111,7 +111,7 @@ jobs: if: branch !~ -prefix$ install: - sudo apt-get install libfuse-dev - - git clone --depth 1 https://github.com/geky/littlefs-fuse -b v2-alpha + - git clone --depth 1 https://github.com/geky/littlefs-fuse -b v2 - fusermount -V - gcc --version before_script: @@ -146,7 +146,7 @@ jobs: if: branch !~ -prefix$ install: - sudo apt-get install libfuse-dev - - git clone --depth 1 https://github.com/geky/littlefs-fuse -b v2-alpha v2 + - git clone --depth 1 https://github.com/geky/littlefs-fuse -b v2 v2 - git clone --depth 1 https://github.com/geky/littlefs-fuse -b v1 v1 - fusermount -V - gcc --version