Fixed issue with rcache going out-of-date when overlapping pcache

This was a inter-abstraction-layer assumption that won't hold true with
the rbyd blocks.

The whole caching layer probably deserves a rewrite at this point.
This commit is contained in:
Christopher Haster
2022-12-26 22:55:05 -06:00
parent b03420ccfc
commit 471f12c79a
2 changed files with 132 additions and 122 deletions
+10
View File
@@ -253,6 +253,16 @@ static int lfs_bd_prog(lfs_t *lfs,
LFS_ASSERT(block == LFS_BLOCK_INLINE || block < lfs->cfg->block_count); LFS_ASSERT(block == LFS_BLOCK_INLINE || block < lfs->cfg->block_count);
LFS_ASSERT(off + size <= lfs->cfg->block_size); LFS_ASSERT(off + size <= lfs->cfg->block_size);
// update rcache if we overlap
if (rcache
&& block == rcache->block
&& off < rcache->off + rcache->size
&& off + size > rcache->off) {
lfs_off_t off_ = lfs_max(off, rcache->off);
lfs_size_t size_ = lfs_min(size, rcache->size - (off_-rcache->off));
memcpy(&rcache->buffer[off_-rcache->off], data+(off_-off), size_);
}
while (size > 0) { while (size > 0) {
if (block == pcache->block && if (block == pcache->block &&
off >= pcache->off && off >= pcache->off &&
+122 -122
View File
@@ -1154,128 +1154,128 @@ code = '''
=> LFS_MKRTAG(GSTATE, 5, 0); => LFS_MKRTAG(GSTATE, 5, 0);
''' '''
#[cases.test_rbyd_prunes] [cases.test_rbyd_prunes]
#in = 'lfs.c' in = 'lfs.c'
#code = ''' code = '''
# lfs_t lfs; lfs_t lfs;
# lfs_init(&lfs, cfg) => 0; lfs_init(&lfs, cfg) => 0;
#
# lfs_rbyd_t rbyd_init = { lfs_rbyd_t rbyd_init = {
# .block = 0, .block = 0,
# .trunk = 0, .trunk = 0,
# .noff = 0, .noff = 0,
# .rev = 1, .rev = 1,
# .crc = 0, .crc = 0,
# .count = 0, .count = 0,
# .erased = true, .erased = true,
# }; };
# lfs_rbyd_t rbyd; lfs_rbyd_t rbyd;
# lfs_off_t off; lfs_off_t off;
# lfs_size_t size; lfs_size_t size;
#
# // don't prune // don't prune
# // <b <b // <b <b
# // .-'| .----'| // .-'| .----'|
# // <y | <y | // <y | <y |
# // .-------'| | .-------'| | // .-------'| | .-------'| |
# // | <r | | <r | // | <r | | <r |
# // | .----' | => | .----' | // | .----' | => | .----' |
# // | | <r | | <r // | | <r | | <r
# // | | .----'| | | .-------'| // | | .----'| | | .-------'|
# // | | | <b | | | <b // | | | <b | | | <b
# // | | | .-'| | | | .----'| // | | | .-'| | | | .----'|
# // 1 2 3 4 5 1 2 3 4 5 5 // 1 2 3 4 5 1 2 3 4 5 5
# rbyd = rbyd_init; rbyd = rbyd_init;
# lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_bd_erase(&lfs, rbyd.block) => 0;
# lfs_rbyd_commit(&lfs, &rbyd, lfs_rbyd_commit(&lfs, &rbyd,
# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4,
# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4,
# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xeeeeeeee}, 4, LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xeeeeeeee}, 4,
# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xffffffff}, 4, NULL))))))) => 0; LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xffffffff}, 4, NULL))))))) => 0;
#
# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 1, 0); => LFS_MKRTAG(GSTATE, 1, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 2, 0); => LFS_MKRTAG(GSTATE, 2, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 3, 0); => LFS_MKRTAG(GSTATE, 3, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 4, 0); => LFS_MKRTAG(GSTATE, 4, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 5, 0); => LFS_MKRTAG(GSTATE, 5, 0);
#
# // prune by taking a red alt // prune by taking a red alt
# // <b // <b
# // .-'| // .-'|
# // <y | >b // <y | >b
# // .-------'| | .-'| // .-------'| | .-'|
# // | <r | | <b // | <r | | <b
# // | .----' | => .-----------|-'| // | .----' | => .-----------|-'|
# // | | <r | <r | // | | <r | <r |
# // | | .----'| | .----'| | // | | .----'| | .----'| |
# // | | | <b | | <b | // | | | <b | | <b |
# // | | | .-'| | | .-'| | // | | | .-'| | | .-'| |
# // 1 2 3 4 5 1 2 3 4 5 2 // 1 2 3 4 5 1 2 3 4 5 2
# rbyd = rbyd_init; rbyd = rbyd_init;
# lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_bd_erase(&lfs, rbyd.block) => 0;
# lfs_rbyd_commit(&lfs, &rbyd, lfs_rbyd_commit(&lfs, &rbyd,
# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4,
# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4,
# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xeeeeeeee}, 4, LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xeeeeeeee}, 4,
# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xeeeeeeee}, 4, NULL))))))) => 0; LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xeeeeeeee}, 4, NULL))))))) => 0;
#
# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 1, 0); => LFS_MKRTAG(GSTATE, 1, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 2, 0); => LFS_MKRTAG(GSTATE, 2, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 3, 0); => LFS_MKRTAG(GSTATE, 3, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 4, 0); => LFS_MKRTAG(GSTATE, 4, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 5, 0); => LFS_MKRTAG(GSTATE, 5, 0);
#
# // prune by taking a yellow alt (this needs to prune during the rflip) // prune by taking a yellow alt (this needs to prune during the rflip)
# // <b // <b
# // .-'| // .-'|
# // <y | >b // <y | >b
# // .-------'| | .-'| // .-------'| | .-'|
# // | <r | | >b // | <r | | >b
# // | .----' | => .--------|-'| // | .----' | => .--------|-'|
# // | | <r | <r | // | | <r | <r |
# // | | .----'| | .----'| | // | | .----'| | .----'| |
# // | | | <b | | <b | // | | | <b | | <b |
# // | | | .-'| | | .-'| | // | | | .-'| | | .-'| |
# // 1 2 3 4 5 1 2 3 4 5 1 // 1 2 3 4 5 1 2 3 4 5 1
# rbyd = rbyd_init; rbyd = rbyd_init;
# lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_bd_erase(&lfs, rbyd.block) => 0;
# lfs_rbyd_commit(&lfs, &rbyd, lfs_rbyd_commit(&lfs, &rbyd,
# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4,
# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4,
# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xeeeeeeee}, 4, LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xeeeeeeee}, 4,
# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xeeeeeeee}, 4, NULL))))))) => 0; LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xeeeeeeee}, 4, NULL))))))) => 0;
#
# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 1, 0); => LFS_MKRTAG(GSTATE, 1, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 2, 0); => LFS_MKRTAG(GSTATE, 2, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 3, 0); => LFS_MKRTAG(GSTATE, 3, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 4, 0); => LFS_MKRTAG(GSTATE, 4, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 5, 0); => LFS_MKRTAG(GSTATE, 5, 0);
#''' '''
#
#[cases.test_rbyd_sextifoliate] #[cases.test_rbyd_sextifoliate]
#in = 'lfs.c' #in = 'lfs.c'
#code = ''' #code = '''