Fix incorrect checksums for small initial writes in the old store
Details: - Write size should be exactly csum_block_size (4k by default) - Write should be made into a new object (unallocated space) - In this case, the checksum of the block was calculated as if the block was padded with extra (2^32 - size) zero bytes due to a simple integer overflow - As a cherry on the cake, such calculation was 'slightly' slow because it was processing almost 4 GB of zeroes for a small write
This commit is contained in:
@@ -183,7 +183,7 @@ bool blockstore_impl_t::enqueue_write(blockstore_op_t *op)
|
||||
uint32_t end = (op->offset+op->len-1) / dsk.csum_block_size;
|
||||
auto fn = state & BS_ST_BIG_WRITE ? crc32c_pad : crc32c_nopad;
|
||||
if (start == end)
|
||||
data_csums[0] = fn(0, op->buf, op->len, op->offset - start*dsk.csum_block_size, end*dsk.csum_block_size - (op->offset+op->len));
|
||||
data_csums[0] = fn(0, op->buf, op->len, op->offset - start*dsk.csum_block_size, (end+1)*dsk.csum_block_size - (op->offset+op->len));
|
||||
else
|
||||
{
|
||||
// First block
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include "crc32c.h"
|
||||
|
||||
#ifdef WITH_ISAL
|
||||
@@ -394,6 +395,7 @@ static uint8_t zero_page[4096] = {};
|
||||
|
||||
uint32_t crc32c_pad(uint32_t prev_crc, const void *buf, size_t len, size_t left_pad, size_t right_pad)
|
||||
{
|
||||
assert(left_pad < 0x10000000 && right_pad < 0x10000000);
|
||||
uint32_t r = prev_crc;
|
||||
while (left_pad >= 4096)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user