Fix checksum padding during flush
This commit is contained in:
@@ -342,6 +342,13 @@ resume_24:
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// Recheck the object because it could be invalidated again
|
||||||
|
cur_obj = bs->heap->read_entry(cur_oid, &modified_block);
|
||||||
|
if (!cur_obj)
|
||||||
|
{
|
||||||
|
// Abort compaction
|
||||||
|
goto resume_0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bs->heap->mark_object_compacted(cur_obj, compact_lsn);
|
bs->heap->mark_object_compacted(cur_obj, compact_lsn);
|
||||||
// Done
|
// Done
|
||||||
@@ -370,83 +377,53 @@ resume_15:
|
|||||||
goto resume_0;
|
goto resume_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void journal_flusher_co::iterate_partial_overwrites(std::function<int(int, uint32_t, uint32_t)> cb)
|
void journal_flusher_co::iterate_checksum_holes(std::function<void(int & pos, uint32_t hole_start, uint32_t hole_end)> cb)
|
||||||
{
|
{
|
||||||
int prev = 0;
|
bs->find_holes(read_vec, 0, bs->dsk.data_block_size, [&](int & pos, uint32_t hole_start, uint32_t hole_end)
|
||||||
uint32_t prev_begin = 0, prev_end = 0;
|
|
||||||
for (int i = 0; i < read_vec.size() && !(read_vec[i].copy_flags & COPY_BUF_CSUM_FILL); i++)
|
|
||||||
{
|
{
|
||||||
if (!(read_vec[i].copy_flags & COPY_BUF_COALESCED))
|
if (hole_start % bs->dsk.csum_block_size)
|
||||||
{
|
{
|
||||||
if (read_vec[i].offset > prev_end)
|
uint32_t blk_end = hole_start - (hole_start % bs->dsk.csum_block_size) + bs->dsk.csum_block_size;
|
||||||
{
|
cb(pos, hole_start, hole_end < blk_end ? hole_end : blk_end);
|
||||||
if (prev_end > prev_begin &&
|
|
||||||
((prev_begin % bs->dsk.csum_block_size) && prev_begin > big_start ||
|
|
||||||
(prev_end % bs->dsk.csum_block_size) && prev_end < big_end))
|
|
||||||
{
|
|
||||||
i += cb(prev, prev_begin, prev_end);
|
|
||||||
}
|
|
||||||
prev = i;
|
|
||||||
prev_begin = read_vec[i].offset;
|
|
||||||
}
|
|
||||||
prev_end = read_vec[i].offset + read_vec[i].len;
|
|
||||||
}
|
}
|
||||||
}
|
if ((hole_end % bs->dsk.csum_block_size) &&
|
||||||
if (prev_end > prev_begin &&
|
(!(hole_start % bs->dsk.csum_block_size) || (hole_end / bs->dsk.csum_block_size) != (hole_start / bs->dsk.csum_block_size)))
|
||||||
((prev_begin % bs->dsk.csum_block_size) && prev_begin > big_start ||
|
|
||||||
(prev_end % bs->dsk.csum_block_size) && prev_end < big_end))
|
|
||||||
{
|
|
||||||
cb(prev, prev_begin, prev_end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void journal_flusher_co::iterate_checksum_holes(std::function<void(int, uint32_t, uint32_t)> cb)
|
|
||||||
{
|
|
||||||
iterate_partial_overwrites([&](int pos, uint32_t prev_begin, uint32_t prev_end)
|
|
||||||
{
|
|
||||||
int r = 0;
|
|
||||||
if ((prev_begin % bs->dsk.csum_block_size) && prev_begin > big_start &&
|
|
||||||
(prev_begin / bs->dsk.csum_block_size) != (prev_end / bs->dsk.csum_block_size))
|
|
||||||
{
|
{
|
||||||
uint32_t blk_begin = (prev_begin - prev_begin%bs->dsk.csum_block_size);
|
cb(pos, hole_end - (hole_end % bs->dsk.csum_block_size), hole_end);
|
||||||
if (blk_begin < big_start)
|
|
||||||
blk_begin = big_start;
|
|
||||||
cb(pos++, blk_begin, prev_begin);
|
|
||||||
r++;
|
|
||||||
}
|
}
|
||||||
if ((prev_end % bs->dsk.csum_block_size) && prev_end < big_end)
|
|
||||||
{
|
|
||||||
uint32_t blk_end = prev_end - (prev_end % bs->dsk.csum_block_size) + bs->dsk.csum_block_size;
|
|
||||||
if (blk_end > big_end)
|
|
||||||
blk_end = big_end;
|
|
||||||
cb(++pos, prev_end, blk_end);
|
|
||||||
r++;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void journal_flusher_co::fill_partial_checksum_blocks()
|
void journal_flusher_co::fill_partial_checksum_blocks()
|
||||||
{
|
{
|
||||||
iterate_checksum_holes([&](int vec_pos, uint32_t hole_start, uint32_t hole_end)
|
iterate_checksum_holes([&](int & vec_pos, uint32_t hole_start, uint32_t hole_end)
|
||||||
{
|
{
|
||||||
read_to_fill_incomplete = true;
|
read_to_fill_incomplete = true;
|
||||||
uint32_t blk_begin = (hole_start - hole_start % bs->dsk.csum_block_size);
|
uint32_t blk_begin = (hole_start - hole_start % bs->dsk.csum_block_size);
|
||||||
bs->prepare_disk_read(read_vec, read_vec.size(), cur_obj, end_wr,
|
blk_begin = (blk_begin < big_start ? big_start : blk_begin);
|
||||||
blk_begin < big_start ? big_start : blk_begin,
|
uint32_t blk_end = (blk_begin + bs->dsk.csum_block_size) > big_end ? big_end : (blk_begin + bs->dsk.csum_block_size);
|
||||||
(blk_begin + bs->dsk.csum_block_size) > big_end ? big_end : (blk_begin + bs->dsk.csum_block_size),
|
uint32_t copy_flags = COPY_BUF_CSUM_FILL | (bs->perfect_csum_update ? 0 : COPY_BUF_SKIP_CSUM);
|
||||||
blk_begin < big_start ? big_start : blk_begin,
|
if (!read_vec.size() || read_vec.back().copy_flags != copy_flags ||
|
||||||
(blk_begin + bs->dsk.csum_block_size) > big_end ? big_end : (blk_begin + bs->dsk.csum_block_size),
|
read_vec.back().offset != blk_begin || read_vec.back().len != blk_end-blk_begin)
|
||||||
COPY_BUF_CSUM_FILL | (bs->perfect_csum_update ? 0 : COPY_BUF_SKIP_CSUM));
|
{
|
||||||
|
read_vec.push_back((copy_buffer_t){
|
||||||
|
.copy_flags = COPY_BUF_DATA | copy_flags,
|
||||||
|
.offset = blk_begin,
|
||||||
|
.len = blk_end - blk_begin,
|
||||||
|
.disk_offset = end_wr->location + blk_begin,
|
||||||
|
.disk_len = blk_end - blk_begin,
|
||||||
|
.buf = (uint8_t*)memalign_or_die(MEM_ALIGNMENT, blk_end - blk_begin),
|
||||||
|
.wr_lsn = end_wr->lsn,
|
||||||
|
});
|
||||||
|
}
|
||||||
auto & vec = read_vec[read_vec.size()-1];
|
auto & vec = read_vec[read_vec.size()-1];
|
||||||
if (!vec.buf)
|
|
||||||
vec.buf = (uint8_t*)memalign_or_die(MEM_ALIGNMENT, vec.disk_len);
|
|
||||||
read_vec.insert(read_vec.begin()+vec_pos, (copy_buffer_t){
|
read_vec.insert(read_vec.begin()+vec_pos, (copy_buffer_t){
|
||||||
.copy_flags = COPY_BUF_JOURNAL|COPY_BUF_COALESCED,
|
.copy_flags = COPY_BUF_JOURNAL|COPY_BUF_COALESCED,
|
||||||
.offset = hole_start,
|
.offset = hole_start,
|
||||||
.len = hole_end-hole_start,
|
.len = hole_end - hole_start,
|
||||||
.buf = vec.buf + hole_start - vec.offset,
|
.buf = vec.buf + hole_start - vec.offset,
|
||||||
});
|
});
|
||||||
|
vec_pos++;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,11 +502,18 @@ int journal_flusher_co::check_and_punch_checksums()
|
|||||||
uint8_t *bmp = end_wr->get_int_bitmap(bs->heap);
|
uint8_t *bmp = end_wr->get_int_bitmap(bs->heap);
|
||||||
uint8_t *csums = end_wr->get_checksums(bs->heap);
|
uint8_t *csums = end_wr->get_checksums(bs->heap);
|
||||||
// Clear bits
|
// Clear bits
|
||||||
iterate_partial_overwrites([&](int pos, uint32_t start, uint32_t end)
|
for (auto & vec: read_vec)
|
||||||
{
|
{
|
||||||
bitmap_clear(bmp, start, end-start, bs->dsk.bitmap_granularity);
|
if (vec.copy_flags & COPY_BUF_CSUM_FILL)
|
||||||
return 0;
|
{
|
||||||
});
|
break;
|
||||||
|
}
|
||||||
|
if (!(vec.copy_flags & COPY_BUF_COALESCED) &&
|
||||||
|
((vec.offset % bs->dsk.csum_block_size) || (vec.len % bs->dsk.csum_block_size)))
|
||||||
|
{
|
||||||
|
bitmap_clear(bmp, vec.offset, vec.len, bs->dsk.bitmap_granularity);
|
||||||
|
}
|
||||||
|
}
|
||||||
// Update partial block checksums
|
// Update partial block checksums
|
||||||
for (auto & vec: read_vec)
|
for (auto & vec: read_vec)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -60,8 +60,7 @@ class journal_flusher_co
|
|||||||
|
|
||||||
friend class journal_flusher_t;
|
friend class journal_flusher_t;
|
||||||
|
|
||||||
void iterate_partial_overwrites(std::function<int(int, uint32_t, uint32_t)> cb);
|
void iterate_checksum_holes(std::function<void(int & pos, uint32_t hole_start, uint32_t hole_end)> cb);
|
||||||
void iterate_checksum_holes(std::function<void(int, uint32_t, uint32_t)> cb);
|
|
||||||
void fill_partial_checksum_blocks();
|
void fill_partial_checksum_blocks();
|
||||||
void free_buffers();
|
void free_buffers();
|
||||||
int check_and_punch_checksums();
|
int check_and_punch_checksums();
|
||||||
|
|||||||
@@ -661,9 +661,9 @@ bool blockstore_heap_t::calc_block_checksums(uint32_t *block_csums, uint8_t *bit
|
|||||||
bool isset = false;
|
bool isset = false;
|
||||||
while (pos < end)
|
while (pos < end)
|
||||||
{
|
{
|
||||||
|
uint32_t prev = pos;
|
||||||
if (bitmap)
|
if (bitmap)
|
||||||
{
|
{
|
||||||
uint32_t prev = pos;
|
|
||||||
while (pos < end && pos < block_end)
|
while (pos < end && pos < block_end)
|
||||||
{
|
{
|
||||||
while (pos < end && pos < block_end && !(bitmap[pos/dsk->bitmap_granularity/8] & (1 << ((pos/dsk->bitmap_granularity) % 8))))
|
while (pos < end && pos < block_end && !(bitmap[pos/dsk->bitmap_granularity/8] & (1 << ((pos/dsk->bitmap_granularity) % 8))))
|
||||||
@@ -696,7 +696,7 @@ bool blockstore_heap_t::calc_block_checksums(uint32_t *block_csums, uint8_t *bit
|
|||||||
{
|
{
|
||||||
if (bad_block_cb)
|
if (bad_block_cb)
|
||||||
{
|
{
|
||||||
bad_block_cb(block_end, *block_csums, block_crc);
|
bad_block_cb(prev, *block_csums, block_crc);
|
||||||
res = false;
|
res = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user