From db14037ac844539c96d02297df29061ee466afbd Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Sun, 13 Jul 2025 17:56:40 +0300 Subject: [PATCH] Fix collapsing intent-over-intent checksums --- src/blockstore/blockstore_heap.cpp | 6 ++++++ src/test/test_heap.cpp | 16 +++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/blockstore/blockstore_heap.cpp b/src/blockstore/blockstore_heap.cpp index 4bfcde9b..956422ae 100644 --- a/src/blockstore/blockstore_heap.cpp +++ b/src/blockstore/blockstore_heap.cpp @@ -1332,6 +1332,12 @@ int blockstore_heap_t::update_object(uint32_t block_num, heap_object_t *obj, hea assert(wr->flags == (BS_HEAP_INTENT_WRITE|BS_HEAP_STABLE)); auto second_wr = first_wr->next(); bitmap_set(second_wr->get_int_bitmap(this), first_wr->offset, first_wr->len, dsk->bitmap_granularity); + if (dsk->csum_block_size && wr->can_be_collapsed(this)) + { + const uint32_t csum_size = (dsk->data_csum_type & 0xFF); + memcpy(second_wr->get_checksums(this) + first_wr->offset/dsk->csum_block_size*csum_size, + first_wr->get_checksums(this), first_wr->len/dsk->csum_block_size*csum_size); + } used_delta -= free_writes(first_wr, second_wr); new_wr->next_pos = (uint8_t*)second_wr - (uint8_t*)new_wr; } diff --git a/src/test/test_heap.cpp b/src/test/test_heap.cpp index 42e775be..8cddc233 100644 --- a/src/test/test_heap.cpp +++ b/src/test/test_heap.cpp @@ -75,7 +75,7 @@ int _test_do_big_write(blockstore_heap_t & heap, blockstore_disk_t & dsk, uint64 ? dsk.data_block_size/dsk.csum_block_size*4 : 0)); memset(wr->get_ext_bitmap(&heap), 0xff, dsk.clean_entry_bitmap_size); if (dsk.csum_block_size) - memset(wr->get_checksums(&heap), 0xab, dsk.data_block_size/dsk.csum_block_size*4); + memset(wr->get_checksums(&heap), 0xde, dsk.data_block_size/dsk.csum_block_size*4); uint32_t mblock; return heap.post_write(oid, wr, &mblock); } @@ -411,6 +411,13 @@ void test_compact(bool csum, bool stable) assert(obj->get_writes()->version == 3); bitmap_set(ref_int_bitmap, 8192, 4096, 4096); assert(!memcmp(obj->get_writes()->get_int_bitmap(&heap), ref_int_bitmap, dsk.clean_entry_bitmap_size)); + if (csum) + { + uint8_t ref_csums[dsk.data_block_size/dsk.csum_block_size*4]; + memset(ref_csums, 0xde, sizeof(ref_csums)); + memset(ref_csums+8, 0xab, 4); + assert(!memcmp(obj->get_writes()->get_checksums(&heap), ref_csums, sizeof(ref_csums))); + } obj = heap.read_entry({ .inode = INODE_WITH_POOL(1, 2), .stripe = 0 }, NULL); assert(obj); @@ -1518,6 +1525,13 @@ void test_intent_write(bool csum) bitmap_set(ref_int_bitmap, 0, 4096, 4096); bitmap_set(ref_int_bitmap, 8192, 4096, 4096); assert(!memcmp(obj->get_writes()->next()->get_int_bitmap(&heap), ref_int_bitmap, dsk.clean_entry_bitmap_size)); + if (csum) + { + uint8_t ref_csums[dsk.data_block_size/dsk.csum_block_size*4]; + memset(ref_csums, 0xde, sizeof(ref_csums)); + memset(ref_csums+8, 0xab, 4); + assert(!memcmp(obj->get_writes()->next()->get_checksums(&heap), ref_csums, sizeof(ref_csums))); + } assert(check_used_space(heap, dsk, 0)); }