Fix a bs_read bug
This commit is contained in:
@@ -224,7 +224,7 @@ resume_1:
|
|||||||
}
|
}
|
||||||
assert(!end_wr->next() && end_wr->flags == (BS_HEAP_BIG_WRITE|BS_HEAP_STABLE));
|
assert(!end_wr->next() && end_wr->flags == (BS_HEAP_BIG_WRITE|BS_HEAP_STABLE));
|
||||||
clean_loc = end_wr->location;
|
clean_loc = end_wr->location;
|
||||||
if (bs->log_level > 9)
|
if (bs->log_level > 10)
|
||||||
printf("Compacting %jx:%jx l%ju .. l%ju (last l%ju)\n", cur_oid.inode, cur_oid.stripe, end_wr->lsn, begin_wr->lsn, compact_lsn);
|
printf("Compacting %jx:%jx l%ju .. l%ju (last l%ju)\n", cur_oid.inode, cur_oid.stripe, end_wr->lsn, begin_wr->lsn, compact_lsn);
|
||||||
flusher->active_flushers++;
|
flusher->active_flushers++;
|
||||||
// Scan versions to flush
|
// Scan versions to flush
|
||||||
@@ -344,7 +344,7 @@ resume_24:
|
|||||||
}
|
}
|
||||||
bs->heap->mark_object_compacted(cur_obj, compact_lsn);
|
bs->heap->mark_object_compacted(cur_obj, compact_lsn);
|
||||||
// Done
|
// Done
|
||||||
if (bs->log_level > 9)
|
if (bs->log_level > 10)
|
||||||
printf("Compacted %jx:%jx l%ju (%d writes)\n", cur_oid.inode, cur_oid.stripe, compact_lsn, copy_count);
|
printf("Compacted %jx:%jx l%ju (%d writes)\n", cur_oid.inode, cur_oid.stripe, compact_lsn, copy_count);
|
||||||
flusher->compact_counter++;
|
flusher->compact_counter++;
|
||||||
flusher->active_flushers--;
|
flusher->active_flushers--;
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ int blockstore_impl_t::dequeue_read(blockstore_op_t *op)
|
|||||||
if (!result_version)
|
if (!result_version)
|
||||||
{
|
{
|
||||||
// May happen if there are entries but all of them are > requested version
|
// May happen if there are entries but all of them are > requested version
|
||||||
|
heap->unlock_entry(op->oid, PRIV(op)->lsn);
|
||||||
op->version = 0;
|
op->version = 0;
|
||||||
op->retval = -ENOENT;
|
op->retval = -ENOENT;
|
||||||
FINISH_OP(op);
|
FINISH_OP(op);
|
||||||
@@ -62,6 +63,7 @@ int blockstore_impl_t::dequeue_read(blockstore_op_t *op)
|
|||||||
if (!PRIV(op)->pending_ops)
|
if (!PRIV(op)->pending_ops)
|
||||||
{
|
{
|
||||||
// everything is fulfilled from memory
|
// everything is fulfilled from memory
|
||||||
|
heap->unlock_entry(op->oid, PRIV(op)->lsn);
|
||||||
op->retval = op->len;
|
op->retval = op->len;
|
||||||
free_read_buffers(rv);
|
free_read_buffers(rv);
|
||||||
FINISH_OP(op);
|
FINISH_OP(op);
|
||||||
@@ -115,10 +117,10 @@ uint32_t blockstore_impl_t::prepare_read(std::vector<copy_buffer_t> & read_vec,
|
|||||||
|
|
||||||
uint32_t blockstore_impl_t::prepare_read_with_bitmaps(std::vector<copy_buffer_t> & read_vec, heap_object_t *obj, heap_write_t *wr, uint32_t start, uint32_t end)
|
uint32_t blockstore_impl_t::prepare_read_with_bitmaps(std::vector<copy_buffer_t> & read_vec, heap_object_t *obj, heap_write_t *wr, uint32_t start, uint32_t end)
|
||||||
{
|
{
|
||||||
// BIG_WRITEs contain a bitmap and we have to handle its holes at the upper level, especially with padded checksums
|
// BIG_WRITEs contain a bitmap and we have to handle its holes
|
||||||
uint32_t res = 0;
|
uint32_t res = 0;
|
||||||
uint8_t *bmp = wr->get_int_bitmap(heap);
|
uint8_t *bmp = wr->get_int_bitmap(heap);
|
||||||
uint32_t bmp_start = 0, bmp_end = 0, bmp_size = dsk.data_block_size/dsk.bitmap_granularity;
|
uint32_t bmp_start = start/dsk.bitmap_granularity, bmp_end = bmp_start, bmp_size = end/dsk.bitmap_granularity;
|
||||||
while (bmp_start < bmp_size)
|
while (bmp_start < bmp_size)
|
||||||
{
|
{
|
||||||
while (bmp_end < bmp_size && !(bmp[bmp_end >> 3] & (1 << (bmp_end & 0x7))))
|
while (bmp_end < bmp_size && !(bmp[bmp_end >> 3] & (1 << (bmp_end & 0x7))))
|
||||||
|
|||||||
@@ -194,6 +194,7 @@ static void test_simple()
|
|||||||
op.len = 128*1024;
|
op.len = 128*1024;
|
||||||
test.exec_op(&op);
|
test.exec_op(&op);
|
||||||
assert(op.retval == op.len);
|
assert(op.retval == op.len);
|
||||||
|
assert(op.version == 1);
|
||||||
uint8_t *cmp = (uint8_t*)memalign_or_die(MEM_ALIGNMENT, 128*1024);
|
uint8_t *cmp = (uint8_t*)memalign_or_die(MEM_ALIGNMENT, 128*1024);
|
||||||
memset(cmp, 0, 128*1024);
|
memset(cmp, 0, 128*1024);
|
||||||
memset(cmp+16384, 0xaa, 4096);
|
memset(cmp+16384, 0xaa, 4096);
|
||||||
@@ -204,6 +205,25 @@ static void test_simple()
|
|||||||
printf("read returned incorrect data\n");
|
printf("read returned incorrect data\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Zero-length read
|
||||||
|
printf("reading 0-0\n");
|
||||||
|
op.version = UINT64_MAX;
|
||||||
|
op.offset = 0;
|
||||||
|
op.len = 0;
|
||||||
|
test.exec_op(&op);
|
||||||
|
assert(op.retval == op.len);
|
||||||
|
assert(op.version == 1);
|
||||||
|
|
||||||
|
// Small read
|
||||||
|
printf("reading 16K-24K\n");
|
||||||
|
op.version = UINT64_MAX;
|
||||||
|
op.offset = 16*1024;
|
||||||
|
op.len = 8*1024;
|
||||||
|
test.exec_op(&op);
|
||||||
|
assert(op.retval == op.len);
|
||||||
|
assert(!memcmp(op.buf, cmp+16*1024, 8*1024));
|
||||||
|
|
||||||
free(cmp);
|
free(cmp);
|
||||||
|
|
||||||
free(op.buf);
|
free(op.buf);
|
||||||
|
|||||||
Reference in New Issue
Block a user