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
path: root/lfs.c
diff options
context:
space:
mode:
authorChristopher Haster <chaster@utexas.edu>2018-04-07 01:00:29 +0300
committerChristopher Haster <chaster@utexas.edu>2018-04-09 22:37:35 +0300
commit89a7630d84f1529549f6aa2528fb7b22f4edf1b2 (patch)
treee5c320e719c8cd9678414f62ec43174caa1e0227 /lfs.c
parent43eac3083bda95006a9cfaea743e95bb358b5bc5 (diff)
Fixed issue with lookahead trusting old lookahead blocks
One of the big simplifications in littlefs's implementation is the complete lack of tracking free blocks, allowing operations to simply drop blocks that are no longer in use. However, this means the lookahead buffer can easily contain outdated blocks that were previously deleted. This is usually fine, as littlefs will rescan the storage if it can't find a free block in the lookahead buffer, but after changes that caused littlefs to more conservatively respect the alloc acks (e611cf5), any scanned blocks after an ack would be incorrectly trusted. The fix is to eagerly scan ahead in the lookahead when we allocate so that alloc acks are better able to discredit old lookahead blocks. Since usually alloc acks are tightly coupled to allocations of one or two blocks, this allows littlefs to properly rescan every set of allocations. This may still be a concern if there is a long series of worn out blocks, but in the worst case littlefs will conservatively avoid using blocks it's not sure about. Found by davidefer
Diffstat (limited to 'lfs.c')
-rw-r--r--lfs.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/lfs.c b/lfs.c
index 4b41e94..b810e51 100644
--- a/lfs.c
+++ b/lfs.c
@@ -290,6 +290,15 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
if (!(lfs->free.buffer[off / 32] & (1U << (off % 32)))) {
// found a free block
*block = (lfs->free.begin + off) % lfs->cfg->block_count;
+
+ // eagerly find next off so an alloc ack can
+ // discredit old lookahead blocks
+ while (lfs->free.off != lfs->free.size &&
+ (lfs->free.buffer[lfs->free.off / 32] &
+ (1U << (lfs->free.off % 32)))) {
+ lfs->free.off += 1;
+ }
+
return 0;
}
}
@@ -315,7 +324,7 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
}
static void lfs_alloc_ack(lfs_t *lfs) {
- lfs->free.ack = lfs->free.off-1 + lfs->free.begin + lfs->cfg->block_count;
+ lfs->free.ack = lfs->free.begin+lfs->free.off + lfs->cfg->block_count;
}