Reworked rbyd/btree/mdir structs again so redund blocks are at the end
For a couple reasons:
1. Organizing the overlaps this way avoid potential undefined behavior.
It turns out C does define the overlap the "initial sequence" of
union members, as long as the types are the same. But when we
overlapped the block with the size/tag fields in lfsr_btree_t, it was
probably undefined behavior.
At the very least, it would introduce a need for quite a bit of
preprocessing to make it work with different integer sizes and
redundancy levels.
2. Overlapping the blocks at the end of the rbyd struct means our block
array is natural ordered such that the first block is the "active"
block, i.e. the block with the most recent revision count that passes
checksums.
This has been useful as a debugging tool, so I would like to continue
the pattern. It is possible to mostly preserve this order with the
previous method by intentional reversing the block array when
logging or writing to disk, but it's a bit cumbersome.
2. It's unlikely we'll be able to use readonly variants of the rbyd/mdir
structs for RAM savings. Unfortunately C makes this too cumbersome.
Though if we do this should be revisited.
Here are the new overlaps. Note it's no longer possible to truncate the
types when readonly. If readonly struct are useful this will need to be
revisited again:
lfsr_rbyd_t lfsr_btree_t lfsr_mdir_t
8b 8b 8b 8b
.----+----+----+----.
8b 8b 8b 8b 8b 8b 8b 8b | mid.bid | mid.rid |
.----+----+----+----. .----+----+----+----. |----+----+----+----|
| weight |.>| weight | | weight |
|----+----+----+----| |----+----+----+----| |----+----+----+----|
| trunk | | tag | size | | trunk |
|----+----+----+----| |----+----+----+----| |----+----+----+----|
| off | | inlined data | | off |
|----+----+----+----| | | | |----+----+----+----|
| crc | | v | | crc |
|----+----+----+----| | | |----+----+----+----|
| block |..| |.>| blocks |
'----+----+----+----' '----+----+----+----' | |
| |
'----+----+----+----'
This commit is contained in:
@@ -5640,9 +5640,9 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
"-> 0x{%"PRIx32",%"PRIx32"}"
|
||||
", 0x{%"PRIx32",%"PRIx32"}",
|
||||
mdir->mid.bid,
|
||||
mdir->u.m.blocks[1], mdir->u.m.blocks[0],
|
||||
mdir_.u.m.blocks[1], mdir_.u.m.blocks[0],
|
||||
msibling_.u.m.blocks[1], msibling_.u.m.blocks[0]);
|
||||
mdir->u.m.blocks[0], mdir->u.m.blocks[1],
|
||||
mdir_.u.m.blocks[0], mdir_.u.m.blocks[1],
|
||||
msibling_.u.m.blocks[0], msibling_.u.m.blocks[1]);
|
||||
|
||||
// because of defered commits, both children can still be reduced
|
||||
// to zero, need to catch this here
|
||||
@@ -5651,10 +5651,10 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
if (mdir_.u.m.weight == 0 && msibling_.u.m.weight == 0) {
|
||||
LFS_DEBUG("Dropping mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"}",
|
||||
mdir_.mid.bid,
|
||||
mdir_.u.m.blocks[1], mdir_.u.m.blocks[0]);
|
||||
mdir_.u.m.blocks[0], mdir_.u.m.blocks[1]);
|
||||
LFS_DEBUG("Dropping mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"}",
|
||||
msibling_.mid.bid,
|
||||
msibling_.u.m.blocks[1], msibling_.u.m.blocks[0]);
|
||||
msibling_.u.m.blocks[0], msibling_.u.m.blocks[1]);
|
||||
// mark as dropped
|
||||
mdir_.u.r.rbyd.trunk = 0;
|
||||
msibling_.u.r.rbyd.trunk = 0;
|
||||
@@ -5669,7 +5669,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
} else if (mdir_.u.m.weight == 0) {
|
||||
LFS_DEBUG("Dropping mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"}",
|
||||
mdir_.mid.bid,
|
||||
mdir_.u.m.blocks[1], mdir_.u.m.blocks[0]);
|
||||
mdir_.u.m.blocks[0], mdir_.u.m.blocks[1]);
|
||||
|
||||
// mark as dropped
|
||||
mdir_.u.r.rbyd.trunk = 0;
|
||||
@@ -5691,7 +5691,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
} else if (msibling_.u.m.weight == 0) {
|
||||
LFS_DEBUG("Dropping mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"}",
|
||||
msibling_.mid.bid,
|
||||
msibling_.u.m.blocks[1], msibling_.u.m.blocks[0]);
|
||||
msibling_.u.m.blocks[0], msibling_.u.m.blocks[1]);
|
||||
|
||||
// mark as dropped
|
||||
msibling_.u.r.rbyd.trunk = 0;
|
||||
@@ -5758,7 +5758,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
} else if (mdir->mid.bid != -1 && mdir_.u.m.weight == 0) {
|
||||
LFS_DEBUG("Dropping mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"}",
|
||||
mdir->mid.bid,
|
||||
mdir->u.m.blocks[1], mdir->u.m.blocks[0]);
|
||||
mdir->u.m.blocks[0], mdir->u.m.blocks[1]);
|
||||
|
||||
// mark as dropped
|
||||
mdir_.u.r.rbyd.trunk = 0;
|
||||
@@ -5784,8 +5784,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
LFS_DEBUG("Relocating mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"} "
|
||||
"-> 0x{%"PRIx32",%"PRIx32"}",
|
||||
mdir->mid.bid,
|
||||
mdir->u.m.blocks[1], mdir->u.m.blocks[0],
|
||||
mdir_.u.m.blocks[1], mdir_.u.m.blocks[0]);
|
||||
mdir->u.m.blocks[0], mdir->u.m.blocks[1],
|
||||
mdir_.u.m.blocks[0], mdir_.u.m.blocks[1]);
|
||||
|
||||
// update our mtree
|
||||
uint8_t buf[LFSR_MDIR_DSIZE];
|
||||
@@ -5918,8 +5918,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
|
||||
LFS_DEBUG("Relocating mroot 0x{%"PRIx32",%"PRIx32"} "
|
||||
"-> 0x{%"PRIx32",%"PRIx32"}",
|
||||
mchildroot.u.m.blocks[1], mchildroot.u.m.blocks[0],
|
||||
mchildroot_[1], mchildroot_[0]);
|
||||
mchildroot.u.m.blocks[0], mchildroot.u.m.blocks[1],
|
||||
mchildroot_[0], mchildroot_[1]);
|
||||
|
||||
// commit mrootchild
|
||||
uint8_t buf[LFSR_MDIR_DSIZE];
|
||||
@@ -5951,9 +5951,9 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
LFS_DEBUG("Extending mroot 0x{%"PRIx32",%"PRIx32"}"
|
||||
" -> 0x{%"PRIx32",%"PRIx32"}"
|
||||
", 0x{%"PRIx32",%"PRIx32"}",
|
||||
mchildroot.u.m.blocks[1], mchildroot.u.m.blocks[0],
|
||||
mchildroot.u.m.blocks[1], mchildroot.u.m.blocks[0],
|
||||
mchildroot_[1], mchildroot_[0]);
|
||||
mchildroot.u.m.blocks[0], mchildroot.u.m.blocks[1],
|
||||
mchildroot.u.m.blocks[0], mchildroot.u.m.blocks[1],
|
||||
mchildroot_[0], mchildroot_[1]);
|
||||
|
||||
// copy magic/config from current mroot
|
||||
lfsr_data_t magic;
|
||||
@@ -6534,7 +6534,7 @@ cycle_detect:;
|
||||
traversal->tortoise_blocks) == 0) {
|
||||
LFS_ERROR("Cycle detected during mtree traversal "
|
||||
"(0x{%"PRIx32",%"PRIx32"})",
|
||||
traversal->mdir.u.m.blocks[1], traversal->mdir.u.m.blocks[0]);
|
||||
traversal->mdir.u.m.blocks[0], traversal->mdir.u.m.blocks[1]);
|
||||
return LFS_ERR_CORRUPT;
|
||||
}
|
||||
if (traversal->tortoise_step
|
||||
|
||||
Reference in New Issue
Block a user