From 471f12c79a33e6c23a3b8f88cf1f109b5ad49e38 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Mon, 26 Dec 2022 22:55:05 -0600 Subject: [PATCH] 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. --- lfs.c | 10 ++ tests/test_rbyd.toml | 244 +++++++++++++++++++++---------------------- 2 files changed, 132 insertions(+), 122 deletions(-) diff --git a/lfs.c b/lfs.c index 38d2cac5..4368dd9a 100644 --- a/lfs.c +++ b/lfs.c @@ -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(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) { if (block == pcache->block && off >= pcache->off && diff --git a/tests/test_rbyd.toml b/tests/test_rbyd.toml index c7b3646e..3d2ff77a 100644 --- a/tests/test_rbyd.toml +++ b/tests/test_rbyd.toml @@ -1154,128 +1154,128 @@ code = ''' => LFS_MKRTAG(GSTATE, 5, 0); ''' -#[cases.test_rbyd_prunes] -#in = 'lfs.c' -#code = ''' -# lfs_t lfs; -# lfs_init(&lfs, cfg) => 0; -# -# lfs_rbyd_t rbyd_init = { -# .block = 0, -# .trunk = 0, -# .noff = 0, -# .rev = 1, -# .crc = 0, -# .count = 0, -# .erased = true, -# }; -# lfs_rbyd_t rbyd; -# lfs_off_t off; -# lfs_size_t size; -# -# // don't prune -# // | .----' | -# // | | 0; -# lfs_rbyd_commit(&lfs, &rbyd, -# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, -# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, -# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 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){0xffffffff}, 4, NULL))))))) => 0; -# -# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; -# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) -# => LFS_MKRTAG(GSTATE, 1, 0); -# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) -# => LFS_MKRTAG(GSTATE, 2, 0); -# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) -# => LFS_MKRTAG(GSTATE, 3, 0); -# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) -# => LFS_MKRTAG(GSTATE, 4, 0); -# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) -# => LFS_MKRTAG(GSTATE, 5, 0); -# -# // prune by taking a red alt -# // b -# // .-------'| | .-'| -# // | .-----------|-'| -# // | | 0; -# lfs_rbyd_commit(&lfs, &rbyd, -# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, -# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, -# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, -# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, -# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xeeeeeeee}, 4, -# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xeeeeeeee}, 4, NULL))))))) => 0; -# -# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; -# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) -# => LFS_MKRTAG(GSTATE, 1, 0); -# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) -# => LFS_MKRTAG(GSTATE, 2, 0); -# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) -# => LFS_MKRTAG(GSTATE, 3, 0); -# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) -# => LFS_MKRTAG(GSTATE, 4, 0); -# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) -# => LFS_MKRTAG(GSTATE, 5, 0); -# -# // prune by taking a yellow alt (this needs to prune during the rflip) -# // b -# // .-------'| | .-'| -# // | b -# // | .----' | => .--------|-'| -# // | | 0; -# lfs_rbyd_commit(&lfs, &rbyd, -# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, -# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, -# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, -# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, -# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xeeeeeeee}, 4, -# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xeeeeeeee}, 4, NULL))))))) => 0; -# -# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; -# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) -# => LFS_MKRTAG(GSTATE, 1, 0); -# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) -# => LFS_MKRTAG(GSTATE, 2, 0); -# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) -# => LFS_MKRTAG(GSTATE, 3, 0); -# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) -# => LFS_MKRTAG(GSTATE, 4, 0); -# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) -# => LFS_MKRTAG(GSTATE, 5, 0); -#''' -# +[cases.test_rbyd_prunes] +in = 'lfs.c' +code = ''' + lfs_t lfs; + lfs_init(&lfs, cfg) => 0; + + lfs_rbyd_t rbyd_init = { + .block = 0, + .trunk = 0, + .noff = 0, + .rev = 1, + .crc = 0, + .count = 0, + .erased = true, + }; + lfs_rbyd_t rbyd; + lfs_off_t off; + lfs_size_t size; + + // don't prune + // | .----' | + // | | 0; + lfs_rbyd_commit(&lfs, &rbyd, + LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, + LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, + LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 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){0xffffffff}, 4, NULL))))))) => 0; + + lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 1, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 2, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 3, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 4, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 5, 0); + + // prune by taking a red alt + // b + // .-------'| | .-'| + // | .-----------|-'| + // | | 0; + lfs_rbyd_commit(&lfs, &rbyd, + LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, + LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, + LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, + LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, + LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xeeeeeeee}, 4, + LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xeeeeeeee}, 4, NULL))))))) => 0; + + lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 1, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 2, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 3, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 4, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 5, 0); + + // prune by taking a yellow alt (this needs to prune during the rflip) + // b + // .-------'| | .-'| + // | b + // | .----' | => .--------|-'| + // | | 0; + lfs_rbyd_commit(&lfs, &rbyd, + LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, + LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, + LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, + LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, + LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xeeeeeeee}, 4, + LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xeeeeeeee}, 4, NULL))))))) => 0; + + lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 1, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 2, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 3, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 4, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 5, 0); +''' + #[cases.test_rbyd_sextifoliate] #in = 'lfs.c' #code = '''