From 9369b643a11771e52bac1bc53e33fdfeb679f002 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Mon, 28 Jul 2025 02:07:28 +0300 Subject: [PATCH] Fix a bs_read bug --- src/blockstore/blockstore_flush.cpp | 4 ++-- src/blockstore/blockstore_read.cpp | 6 ++++-- src/test/test_blockstore.cpp | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/blockstore/blockstore_flush.cpp b/src/blockstore/blockstore_flush.cpp index ae29cc61..eba5f21b 100644 --- a/src/blockstore/blockstore_flush.cpp +++ b/src/blockstore/blockstore_flush.cpp @@ -224,7 +224,7 @@ resume_1: } assert(!end_wr->next() && end_wr->flags == (BS_HEAP_BIG_WRITE|BS_HEAP_STABLE)); 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); flusher->active_flushers++; // Scan versions to flush @@ -344,7 +344,7 @@ resume_24: } bs->heap->mark_object_compacted(cur_obj, compact_lsn); // 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); flusher->compact_counter++; flusher->active_flushers--; diff --git a/src/blockstore/blockstore_read.cpp b/src/blockstore/blockstore_read.cpp index 2c65691b..96f73071 100644 --- a/src/blockstore/blockstore_read.cpp +++ b/src/blockstore/blockstore_read.cpp @@ -44,6 +44,7 @@ int blockstore_impl_t::dequeue_read(blockstore_op_t *op) if (!result_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->retval = -ENOENT; FINISH_OP(op); @@ -62,6 +63,7 @@ int blockstore_impl_t::dequeue_read(blockstore_op_t *op) if (!PRIV(op)->pending_ops) { // everything is fulfilled from memory + heap->unlock_entry(op->oid, PRIV(op)->lsn); op->retval = op->len; free_read_buffers(rv); FINISH_OP(op); @@ -115,10 +117,10 @@ uint32_t blockstore_impl_t::prepare_read(std::vector & read_vec, uint32_t blockstore_impl_t::prepare_read_with_bitmaps(std::vector & 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; 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_end < bmp_size && !(bmp[bmp_end >> 3] & (1 << (bmp_end & 0x7)))) diff --git a/src/test/test_blockstore.cpp b/src/test/test_blockstore.cpp index 3dd5cf8e..8a4ef460 100644 --- a/src/test/test_blockstore.cpp +++ b/src/test/test_blockstore.cpp @@ -194,6 +194,7 @@ static void test_simple() op.len = 128*1024; test.exec_op(&op); assert(op.retval == op.len); + assert(op.version == 1); uint8_t *cmp = (uint8_t*)memalign_or_die(MEM_ALIGNMENT, 128*1024); memset(cmp, 0, 128*1024); memset(cmp+16384, 0xaa, 4096); @@ -204,6 +205,25 @@ static void test_simple() printf("read returned incorrect data\n"); 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(op.buf);