Fix journal data checksum mangling on corrupted block overwrite

hotfix-1.0.0
Vitaliy Filippov 2023-06-11 11:09:22 +03:00
parent ddb078d5a7
commit 71674d00cf
2 changed files with 10 additions and 6 deletions

View File

@ -773,13 +773,17 @@ bool journal_flusher_co::clear_incomplete_csum_block_bits(int wait_base)
{
bs->verify_journal_checksums(v[i].csum_buf, v[i].offset, &iov, 1, [&](uint32_t bad_block, uint32_t calc_csum, uint32_t stored_csum)
{
printf("Checksum mismatch in object %lx:%lx v%lu in journal at offset 0x%lx+0x%x: got %08x, expected %08x\n",
printf("Checksum mismatch in object %lx:%lx v%lu in journal at offset 0x%lx+0x%x (block offset 0x%lx): got %08x, expected %08x\n",
cur.oid.inode, cur.oid.stripe, old_clean_ver,
v[i].disk_offset, bad_block, calc_csum, stored_csum);
uint32_t bad_block_end = ((bad_block/bs->dsk.csum_block_size)+1)*bs->dsk.csum_block_size -
v[i].offset % bs->dsk.csum_block_size;
v[i].disk_offset, bad_block, v[i].offset, calc_csum, stored_csum);
bad_block += (v[i].offset/bs->dsk.csum_block_size) * bs->dsk.csum_block_size;
uint32_t bad_block_end = bad_block + bs->dsk.csum_block_size + (v[i].offset/bs->dsk.csum_block_size) * bs->dsk.csum_block_size;
if (bad_block < v[i].offset)
bad_block = v[i].offset;
if (bad_block_end > v[i].offset+v[i].len)
bad_block_end = v[i].offset+v[i].len;
bad_block -= v[i].offset;
bad_block_end -= v[i].offset;
for (uint32_t j = bad_block; j < bad_block_end; j += bs->dsk.bitmap_granularity)
{
// Simplest method of mangling: flip one byte in every sector

View File

@ -731,7 +731,7 @@ bool blockstore_impl_t::verify_journal_checksums(uint8_t *csums, uint32_t offset
if (block_csum != ((uint32_t*)csums)[block_num])
{
if (bad_block_cb)
bad_block_cb(block_num*dsk.csum_block_size - (offset%dsk.csum_block_size), block_csum, ((uint32_t*)csums)[block_num]);
bad_block_cb(block_num*dsk.csum_block_size, block_csum, ((uint32_t*)csums)[block_num]);
else
return false;
}
@ -749,7 +749,7 @@ bool blockstore_impl_t::verify_journal_checksums(uint8_t *csums, uint32_t offset
if (block_done > 0 && block_csum != ((uint32_t*)csums)[block_num])
{
if (bad_block_cb)
bad_block_cb(block_num*dsk.csum_block_size - (offset%dsk.csum_block_size), block_csum, ((uint32_t*)csums)[block_num]);
bad_block_cb(block_num*dsk.csum_block_size, block_csum, ((uint32_t*)csums)[block_num]);
else
return false;
}