Disable punching block checksums and allow to enable it with a parameter
This commit is contained in:
@@ -253,7 +253,7 @@ resume_1:
|
||||
{
|
||||
// Read original checksum blocks to calculate padded checksums if required
|
||||
fill_partial_checksum_blocks();
|
||||
if (read_to_fill_incomplete)
|
||||
if (read_to_fill_incomplete && bs->padded_csum_update)
|
||||
{
|
||||
flusher->wanting_meta_fsync++;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ resume_3:
|
||||
// we'll have a correct checksum because it won't include overwritten parts!
|
||||
// The same thing actually happens even when csum_block_size == bitmap_granularity, but in that case
|
||||
// we never need to read (and thus verify) overwritten parts from the data device.
|
||||
if (read_to_fill_incomplete)
|
||||
if (read_to_fill_incomplete && bs->padded_csum_update)
|
||||
{
|
||||
flusher->wanting_meta_fsync--;
|
||||
}
|
||||
@@ -422,17 +422,17 @@ void journal_flusher_co::fill_partial_checksum_blocks()
|
||||
iterate_checksum_holes([&](int vec_pos, uint32_t hole_start, uint32_t hole_end)
|
||||
{
|
||||
read_to_fill_incomplete = true;
|
||||
int pos = read_vec.size();
|
||||
bs->prepare_disk_read(read_vec, pos, cur_obj, end_wr,
|
||||
int out_pos = read_vec.size();
|
||||
bs->prepare_disk_read(read_vec, out_pos, cur_obj, end_wr,
|
||||
hole_start - hole_start % bs->dsk.csum_block_size, hole_start - hole_start % bs->dsk.csum_block_size + bs->dsk.csum_block_size,
|
||||
hole_start - hole_start % bs->dsk.csum_block_size, hole_start - hole_start % bs->dsk.csum_block_size + bs->dsk.csum_block_size);
|
||||
pos--;
|
||||
read_vec[pos].copy_flags |= COPY_BUF_CSUM_FILL;
|
||||
hole_start - hole_start % bs->dsk.csum_block_size, hole_start - hole_start % bs->dsk.csum_block_size + bs->dsk.csum_block_size,
|
||||
COPY_BUF_CSUM_FILL | (bs->padded_csum_update ? 0 : COPY_BUF_SKIP_CSUM));
|
||||
out_pos--;
|
||||
read_vec.insert(read_vec.begin()+vec_pos, (copy_buffer_t){
|
||||
.copy_flags = COPY_BUF_JOURNAL|COPY_BUF_COALESCED,
|
||||
.offset = hole_start,
|
||||
.len = hole_end-hole_start,
|
||||
.buf = read_vec[pos].buf + hole_start - read_vec[pos].offset,
|
||||
.buf = read_vec[out_pos].buf + hole_start - read_vec[out_pos].offset,
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -465,7 +465,7 @@ int journal_flusher_co::check_and_punch_checksums()
|
||||
for (int i = 0; i < read_vec.size(); i++)
|
||||
{
|
||||
auto & vec = read_vec[i];
|
||||
if (!(vec.copy_flags & (COPY_BUF_COALESCED|COPY_BUF_ZERO)))
|
||||
if (!(vec.copy_flags & (COPY_BUF_COALESCED|COPY_BUF_ZERO|COPY_BUF_SKIP_CSUM)))
|
||||
{
|
||||
heap_write_t *wr = cur_obj->get_writes();
|
||||
while (wr && wr->lsn != vec.wr_lsn)
|
||||
@@ -490,7 +490,7 @@ int journal_flusher_co::check_and_punch_checksums()
|
||||
// FIXME: Report the corrupted object to the upper layer
|
||||
return EDOM;
|
||||
}
|
||||
if (!read_to_fill_incomplete)
|
||||
if (!read_to_fill_incomplete || !bs->padded_csum_update)
|
||||
{
|
||||
// Nothing to do
|
||||
return 0;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
struct copy_buffer_t
|
||||
{
|
||||
int copy_flags;
|
||||
uint32_t copy_flags;
|
||||
uint64_t offset, len, disk_offset, disk_len;
|
||||
uint8_t *buf;
|
||||
uint64_t wr_lsn;
|
||||
|
||||
@@ -103,6 +103,9 @@ class blockstore_impl_t: public blockstore_i
|
||||
uint64_t autosync_writes = 128;
|
||||
// Log level (0-10)
|
||||
int log_level = 0;
|
||||
// Enable correct block checksum validation on objects updated with small writes when checksum block
|
||||
// is larger than bitmap_granularity, at the expense of extra metadata fsyncs during compaction
|
||||
bool padded_csum_update = false;
|
||||
/******* END OF OPTIONS *******/
|
||||
|
||||
struct ring_consumer_t ring_consumer;
|
||||
@@ -157,7 +160,7 @@ class blockstore_impl_t: public blockstore_i
|
||||
uint32_t prepare_read_zero(std::vector<copy_buffer_t> & read_vec, uint32_t start, uint32_t end);
|
||||
uint32_t prepare_read_simple(std::vector<copy_buffer_t> & read_vec, heap_object_t *obj, heap_write_t *wr, uint32_t start, uint32_t end);
|
||||
void prepare_disk_read(std::vector<copy_buffer_t> & read_vec, int & pos, heap_object_t *obj, heap_write_t *wr,
|
||||
uint32_t blk_start, uint32_t blk_end, uint32_t start, uint32_t end);
|
||||
uint32_t blk_start, uint32_t blk_end, uint32_t start, uint32_t end, uint32_t copy_flags);
|
||||
void find_holes(std::vector<copy_buffer_t> & read_vec, uint32_t item_start, uint32_t item_end,
|
||||
std::function<void(int&, bool, uint32_t, uint32_t)> callback);
|
||||
void handle_read_event(ring_data_t *data, blockstore_op_t *op);
|
||||
|
||||
@@ -47,3 +47,4 @@
|
||||
#define COPY_BUF_CSUM_FILL 8
|
||||
#define COPY_BUF_COALESCED 16
|
||||
#define COPY_BUF_PADDED 32
|
||||
#define COPY_BUF_SKIP_CSUM 64
|
||||
|
||||
@@ -26,6 +26,7 @@ void blockstore_impl_t::parse_config(blockstore_config_t & config, bool init)
|
||||
throttle_target_mbs = strtoull(config["throttle_target_mbs"].c_str(), NULL, 10);
|
||||
throttle_target_parallelism = strtoull(config["throttle_target_parallelism"].c_str(), NULL, 10);
|
||||
throttle_threshold_us = strtoull(config["throttle_threshold_us"].c_str(), NULL, 10);
|
||||
padded_csum_update = config["padded_csum_update"] == "true" || config["padded_csum_update"] == "1" || config["padded_csum_update"] == "yes";
|
||||
if (config["autosync_writes"] != "")
|
||||
{
|
||||
autosync_writes = strtoull(config["autosync_writes"].c_str(), NULL, 10);
|
||||
|
||||
@@ -200,7 +200,7 @@ uint32_t blockstore_impl_t::prepare_read_simple(std::vector<copy_buffer_t> & rea
|
||||
else if (dsk.csum_block_size <= dsk.bitmap_granularity)
|
||||
{
|
||||
// simple disk read
|
||||
prepare_disk_read(read_vec, pos, obj, wr, start, end, start, end);
|
||||
prepare_disk_read(read_vec, pos, obj, wr, start, end, start, end, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -210,12 +210,23 @@ uint32_t blockstore_impl_t::prepare_read_simple(std::vector<copy_buffer_t> & rea
|
||||
blk_start = blk_start < wr->offset ? wr->offset : blk_start;
|
||||
blk_end = ((end-1) / dsk.csum_block_size + 1) * dsk.csum_block_size;
|
||||
blk_end = blk_end > wr->offset+wr->len ? wr->offset+wr->len : blk_end;
|
||||
uint32_t skip_csum = 0;
|
||||
if (!padded_csum_update)
|
||||
{
|
||||
for (auto owr = obj->get_writes(); owr && owr != wr; owr = owr->next())
|
||||
{
|
||||
if (owr->offset < blk_end && owr->offset+owr->len > blk_start)
|
||||
{
|
||||
skip_csum = COPY_BUF_SKIP_CSUM;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (blk_end == blk_start+dsk.csum_block_size ||
|
||||
blk_end == blk_start+2*dsk.csum_block_size && blk_end != end && blk_start != start ||
|
||||
blk_end == end && blk_start == start)
|
||||
{
|
||||
// single block, two partial blocks, or any number of full blocks
|
||||
prepare_disk_read(read_vec, pos, obj, wr, blk_start, blk_end, start, end);
|
||||
prepare_disk_read(read_vec, pos, obj, wr, blk_start, blk_end, start, end, skip_csum);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -223,11 +234,11 @@ uint32_t blockstore_impl_t::prepare_read_simple(std::vector<copy_buffer_t> & rea
|
||||
uint32_t full_start = (blk_start != start ? blk_start+dsk.csum_block_size : blk_start);
|
||||
uint32_t full_end = (blk_end != end ? blk_end-dsk.csum_block_size : blk_end);
|
||||
if (blk_start != start)
|
||||
prepare_disk_read(read_vec, pos, obj, wr, blk_start, full_start, start, full_start);
|
||||
prepare_disk_read(read_vec, pos, obj, wr, blk_start, full_start, start, full_start, skip_csum);
|
||||
if (full_start > full_end)
|
||||
prepare_disk_read(read_vec, pos, obj, wr, full_start, full_end, full_start, full_end);
|
||||
prepare_disk_read(read_vec, pos, obj, wr, full_start, full_end, full_start, full_end, skip_csum);
|
||||
if (blk_end != end)
|
||||
prepare_disk_read(read_vec, pos, obj, wr, full_end, blk_end, full_end, end);
|
||||
prepare_disk_read(read_vec, pos, obj, wr, full_end, blk_end, full_end, end, skip_csum);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -235,10 +246,10 @@ uint32_t blockstore_impl_t::prepare_read_simple(std::vector<copy_buffer_t> & rea
|
||||
}
|
||||
|
||||
void blockstore_impl_t::prepare_disk_read(std::vector<copy_buffer_t> & read_vec, int & pos, heap_object_t *obj, heap_write_t *wr,
|
||||
uint32_t blk_start, uint32_t blk_end, uint32_t start, uint32_t end)
|
||||
uint32_t blk_start, uint32_t blk_end, uint32_t start, uint32_t end, uint32_t copy_flags)
|
||||
{
|
||||
copy_buffer_t vec = {
|
||||
.copy_flags = ((wr->flags & BS_HEAP_TYPE) == BS_HEAP_SMALL_WRITE ? COPY_BUF_JOURNAL : COPY_BUF_DATA),
|
||||
.copy_flags = ((wr->flags & BS_HEAP_TYPE) == BS_HEAP_SMALL_WRITE ? COPY_BUF_JOURNAL : COPY_BUF_DATA) | copy_flags,
|
||||
.offset = start,
|
||||
.len = end-start,
|
||||
.disk_offset = wr->location + blk_start - wr->offset,
|
||||
@@ -326,7 +337,7 @@ bool blockstore_impl_t::verify_read_checksums(blockstore_op_t *op)
|
||||
auto & rv = PRIV(op)->read_vec;
|
||||
for (auto & vec: rv)
|
||||
{
|
||||
if (vec.copy_flags & COPY_BUF_COALESCED)
|
||||
if (vec.copy_flags & (COPY_BUF_COALESCED|COPY_BUF_SKIP_CSUM))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user