Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/littlefs-project/littlefs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Haster <chaster@utexas.edu>2019-01-30 06:53:56 +0300
committerChristopher Haster <chaster@utexas.edu>2019-01-30 07:43:19 +0300
commit95c1a6339ddd9e0dbbc19bf0be0c37f629af2b5d (patch)
tree448e93c20db940dc7485bd23f4108a804b003bb4
parent173c21215159236b2d93caf2856636d29680ef79 (diff)
Fixed corner case in block_cycles eviction logic
The problem was when we allocate a dir-pair, it's possible for the revision count to immediately overflow and the dir-pair be evicted and returned to the unused blocks without being written even once. In the case that block_cycles = 1, this made it impossible to ever create a dir-pair, even in lfs_format. I've also added a bit of logic to lfs_dir_alloc that will prevent any immediate evictions because of the revision count. found by TheLoneWolfling
-rw-r--r--lfs.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/lfs.c b/lfs.c
index d33b282..d4ccb41 100644
--- a/lfs.c
+++ b/lfs.c
@@ -1316,15 +1316,14 @@ static int lfs_dir_alloc(lfs_t *lfs, lfs_mdir_t *dir) {
int err = lfs_bd_read(lfs,
NULL, &lfs->rcache, sizeof(dir->rev),
dir->pair[0], 0, &dir->rev, sizeof(dir->rev));
- if (err) {
- return err;
- }
-
dir->rev = lfs_fromle32(dir->rev);
if (err && err != LFS_ERR_CORRUPT) {
return err;
}
+ // make sure we don't immediately evict
+ dir->rev += dir->rev & 1;
+
// set defaults
dir->off = sizeof(dir->rev);
dir->etag = 0xffffffff;
@@ -1457,7 +1456,8 @@ static int lfs_dir_compact(lfs_t *lfs,
// increment revision count
dir->rev += 1;
- if (lfs->cfg->block_cycles && dir->rev % lfs->cfg->block_cycles == 0) {
+ if (lfs->cfg->block_cycles &&
+ (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,
// should we expand?