Fix some blockstore bugs discovered by the mocked test!
This commit is contained in:
@@ -164,8 +164,8 @@ struct __attribute__ ((visibility("default"))) blockstore_op_t
|
|||||||
uint32_t list_stable_limit;
|
uint32_t list_stable_limit;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
void *buf = NULL;
|
uint8_t *buf = NULL;
|
||||||
void *bitmap = NULL;
|
uint8_t *bitmap = NULL;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
uint8_t private_data[BS_OP_PRIVATE_DATA_SIZE];
|
uint8_t private_data[BS_OP_PRIVATE_DATA_SIZE];
|
||||||
|
|||||||
@@ -566,11 +566,11 @@ bool blockstore_heap_t::calc_block_checksums(uint32_t *block_csums, uint8_t *dat
|
|||||||
bool isset = false;
|
bool isset = false;
|
||||||
while (pos < end)
|
while (pos < end)
|
||||||
{
|
{
|
||||||
|
uint32_t prev = pos;
|
||||||
if (bitmap)
|
if (bitmap)
|
||||||
{
|
{
|
||||||
while (pos < end && pos < block_end)
|
while (pos < end && pos < block_end)
|
||||||
{
|
{
|
||||||
uint32_t prev = pos;
|
|
||||||
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))))
|
||||||
pos += dsk->bitmap_granularity;
|
pos += dsk->bitmap_granularity;
|
||||||
if (pos > prev && (isset || pos < block_end))
|
if (pos > prev && (isset || pos < block_end))
|
||||||
@@ -599,7 +599,7 @@ bool blockstore_heap_t::calc_block_checksums(uint32_t *block_csums, uint8_t *dat
|
|||||||
{
|
{
|
||||||
if (bad_block_cb)
|
if (bad_block_cb)
|
||||||
{
|
{
|
||||||
bad_block_cb(pos-start, *block_csums, block_crc);
|
bad_block_cb(prev-start, *block_csums, block_crc);
|
||||||
res = false;
|
res = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -320,7 +320,7 @@ void blockstore_impl_t::process_list(blockstore_op_t *op)
|
|||||||
int res = heap->list_objects(list_pg, min_inode, max_inode, &result, &stable_count, &unstable_count);
|
int res = heap->list_objects(list_pg, min_inode, max_inode, &result, &stable_count, &unstable_count);
|
||||||
op->version = stable_count;
|
op->version = stable_count;
|
||||||
op->retval = res == 0 ? stable_count+unstable_count : -res;
|
op->retval = res == 0 ? stable_count+unstable_count : -res;
|
||||||
op->buf = result;
|
op->buf = (uint8_t*)result;
|
||||||
FINISH_OP(op);
|
FINISH_OP(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ void blockstore_impl_t::prepare_disk_read(std::vector<copy_buffer_t> & read_vec,
|
|||||||
.copy_flags = ((wr->flags & BS_HEAP_TYPE) == BS_HEAP_SMALL_WRITE ? COPY_BUF_JOURNAL : COPY_BUF_DATA) | copy_flags,
|
.copy_flags = ((wr->flags & BS_HEAP_TYPE) == BS_HEAP_SMALL_WRITE ? COPY_BUF_JOURNAL : COPY_BUF_DATA) | copy_flags,
|
||||||
.offset = start,
|
.offset = start,
|
||||||
.len = end-start,
|
.len = end-start,
|
||||||
.disk_offset = ((wr->flags & BS_HEAP_TYPE) == BS_HEAP_INTENT_WRITE ? wr->next()->location : wr->location) + blk_start - wr->offset,
|
.disk_offset = ((wr->flags & BS_HEAP_TYPE) == BS_HEAP_INTENT_WRITE ? wr->next()->location : wr->location) + blk_start,
|
||||||
.disk_len = blk_end - blk_start,
|
.disk_len = blk_end - blk_start,
|
||||||
.wr_lsn = wr->lsn,
|
.wr_lsn = wr->lsn,
|
||||||
};
|
};
|
||||||
@@ -334,7 +334,7 @@ bool blockstore_impl_t::verify_read_checksums(blockstore_op_t *op)
|
|||||||
auto & rv = PRIV(op)->read_vec;
|
auto & rv = PRIV(op)->read_vec;
|
||||||
for (auto & vec: rv)
|
for (auto & vec: rv)
|
||||||
{
|
{
|
||||||
if (vec.copy_flags & (COPY_BUF_COALESCED|COPY_BUF_SKIP_CSUM))
|
if (vec.copy_flags & (COPY_BUF_COALESCED|COPY_BUF_SKIP_CSUM|COPY_BUF_ZERO))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -351,11 +351,13 @@ bool blockstore_impl_t::verify_read_checksums(blockstore_op_t *op)
|
|||||||
blk_end = blk_end > wr->offset+wr->len ? wr->offset+wr->len : blk_end;
|
blk_end = blk_end > wr->offset+wr->len ? wr->offset+wr->len : blk_end;
|
||||||
memcpy(op->buf + vec.offset - op->offset, vec.buf + vec.offset - blk_start, vec.len);
|
memcpy(op->buf + vec.offset - op->offset, vec.buf + vec.offset - blk_start, vec.len);
|
||||||
}
|
}
|
||||||
if (!heap->calc_block_checksums((uint32_t*)wr->get_checksums(heap), vec.buf, wr->get_int_bitmap(heap),
|
uint8_t *buf = vec.buf ? vec.buf : (op->buf + vec.offset - op->offset);
|
||||||
|
uint32_t *csums = (uint32_t*)(wr->get_checksums(heap) + (blk_start/dsk.csum_block_size)*(dsk.data_csum_type & 0xFF));
|
||||||
|
if (!heap->calc_block_checksums(csums, buf, wr->get_int_bitmap(heap),
|
||||||
blk_start, blk_end, false, [&](uint32_t mismatch_pos, uint32_t expected_csum, uint32_t real_csum)
|
blk_start, blk_end, false, [&](uint32_t mismatch_pos, uint32_t expected_csum, uint32_t real_csum)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
"Checksum mismatch in object %jx:%jx v%ju in %s area at offset 0x%jx+%x: %08x vs %08x\n",
|
"Checksum mismatch in object %jx:%jx v%ju in %s area at offset 0x%jx+%x: %08x expected vs %08x actual\n",
|
||||||
op->oid.inode, op->oid.stripe, op->version,
|
op->oid.inode, op->oid.stripe, op->version,
|
||||||
(vec.copy_flags & COPY_BUF_JOURNAL) ? "buffer" : "data", vec.disk_offset,
|
(vec.copy_flags & COPY_BUF_JOURNAL) ? "buffer" : "data", vec.disk_offset,
|
||||||
mismatch_pos, expected_csum, real_csum
|
mismatch_pos, expected_csum, real_csum
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ resume_1:
|
|||||||
heap->mark_lsn_completed(lsn);
|
heap->mark_lsn_completed(lsn);
|
||||||
}
|
}
|
||||||
// Fsync, just because our semantics imply that commit (stabilize) is immediately fsynced
|
// Fsync, just because our semantics imply that commit (stabilize) is immediately fsynced
|
||||||
|
priv->op_state = 2;
|
||||||
resume_2:
|
resume_2:
|
||||||
resume_3:
|
resume_3:
|
||||||
resume_4:
|
resume_4:
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ static enum fio_q_status bs_queue(struct thread_data *td, struct io_u *io)
|
|||||||
{
|
{
|
||||||
case DDIR_READ:
|
case DDIR_READ:
|
||||||
op->opcode = BS_OP_READ;
|
op->opcode = BS_OP_READ;
|
||||||
op->buf = io->xfer_buf;
|
op->buf = (uint8_t*)io->xfer_buf;
|
||||||
op->oid = {
|
op->oid = {
|
||||||
.inode = 1,
|
.inode = 1,
|
||||||
.stripe = io->offset / bsd->bs->get_block_size(),
|
.stripe = io->offset / bsd->bs->get_block_size(),
|
||||||
@@ -221,7 +221,7 @@ static enum fio_q_status bs_queue(struct thread_data *td, struct io_u *io)
|
|||||||
break;
|
break;
|
||||||
case DDIR_WRITE:
|
case DDIR_WRITE:
|
||||||
op->opcode = bsd->ec ? BS_OP_WRITE : BS_OP_WRITE_STABLE;
|
op->opcode = bsd->ec ? BS_OP_WRITE : BS_OP_WRITE_STABLE;
|
||||||
op->buf = io->xfer_buf;
|
op->buf = (uint8_t*)io->xfer_buf;
|
||||||
op->oid = {
|
op->oid = {
|
||||||
.inode = 1,
|
.inode = 1,
|
||||||
.stripe = io->offset / bsd->bs->get_block_size(),
|
.stripe = io->offset / bsd->bs->get_block_size(),
|
||||||
@@ -247,7 +247,7 @@ static enum fio_q_status bs_queue(struct thread_data *td, struct io_u *io)
|
|||||||
{
|
{
|
||||||
auto stab_op = new blockstore_op_t;
|
auto stab_op = new blockstore_op_t;
|
||||||
stab_op->opcode = BS_OP_STABLE;
|
stab_op->opcode = BS_OP_STABLE;
|
||||||
stab_op->buf = malloc_or_die(sizeof(obj_ver_id));
|
stab_op->buf = (uint8_t*)malloc_or_die(sizeof(obj_ver_id));
|
||||||
obj_ver_id *ver = (obj_ver_id *)stab_op->buf;
|
obj_ver_id *ver = (obj_ver_id *)stab_op->buf;
|
||||||
ver[0].oid = op->oid;
|
ver[0].oid = op->oid;
|
||||||
ver[0].version = op->version;
|
ver[0].version = op->version;
|
||||||
|
|||||||
Reference in New Issue
Block a user