diff --git a/src/cluster_client.cpp b/src/cluster_client.cpp index 17becd08..074e57df 100644 --- a/src/cluster_client.cpp +++ b/src/cluster_client.cpp @@ -673,7 +673,7 @@ bool cluster_client_t::check_rw(cluster_op_t *op) return false; } // Check alignment - if (!op->len && (op->opcode == OSD_OP_READ || op->opcode == OSD_OP_READ_BITMAP || op->opcode == OSD_OP_READ_CHAIN_BITMAP || op->opcode == OSD_OP_WRITE) || + if (!op->len && (op->opcode == OSD_OP_READ_BITMAP || op->opcode == OSD_OP_READ_CHAIN_BITMAP || op->opcode == OSD_OP_WRITE) || op->offset % pool_it->second.bitmap_granularity || op->len % pool_it->second.bitmap_granularity) { op->retval = -EINVAL; diff --git a/src/kv_db.cpp b/src/kv_db.cpp index f1345644..feae0092 100644 --- a/src/kv_db.cpp +++ b/src/kv_db.cpp @@ -887,14 +887,23 @@ static void get_block(kv_db_t *db, uint64_t offset, int cur_level, int recheck_p op->opcode = OSD_OP_READ; op->inode = db->inode_id; op->offset = offset; - op->len = db->kv_block_size; - op->iov.push_back(malloc_or_die(op->len), op->len); + if (b_it != db->block_cache.end() && !b_it->second.invalidated && !b_it->second.updating) + { + // just recheck version - it's cheaper than re-reading the block + op->len = 0; + } + else + { + op->len = db->kv_block_size; + op->iov.push_back(malloc_or_die(op->len), op->len); + } op->callback = [=](cluster_op_t *op) { if (op->retval != op->len) { // error - free(op->iov.buf[0].iov_base); + if (op->len) + free(op->iov.buf[0].iov_base); cb(op->retval >= 0 ? -EIO : op->retval, BLK_NOCHANGE); delete op; return; @@ -909,7 +918,8 @@ static void get_block(kv_db_t *db, uint64_t offset, int cur_level, int recheck_p if (blk->updating > 0 && recheck_policy == KV_RECHECK_WAIT) { // Wait until block update stops - free(op->iov.buf[0].iov_base); + if (op->len) + free(op->iov.buf[0].iov_base); delete op; db->continue_update.emplace(blk->offset, [=, blk_offset = blk->offset]() { @@ -923,6 +933,13 @@ static void get_block(kv_db_t *db, uint64_t offset, int cur_level, int recheck_p } else { + if (!op->len) + { + // Version check failed, re-read block + delete op; + get_block(db, offset, cur_level, recheck_policy, cb); + return; + } auto blk = &db->block_cache[op->offset]; if (blk_it != db->block_cache.end()) { @@ -944,7 +961,8 @@ static void get_block(kv_db_t *db, uint64_t offset, int cur_level, int recheck_p } try_evict(db); } - free(op->iov.buf[0].iov_base); + if (op->len) + free(op->iov.buf[0].iov_base); delete op; }; db->cli->execute(op);