From 1e4263fa5da0534beb53b6cd0d90b4917f9fcad2 Mon Sep 17 00:00:00 2001 From: xie xingguo Date: Sun, 24 Sep 2017 08:58:45 +0800 Subject: [PATCH] osd/PrimaryLogPG: allow trimmed read for OP_CHECKSUM Normal reads support trimmed read length, and so shall checksums! This fixes occasionally failure of rados/thrash test scripts, e.g.: (1) create object using WriteOp with random generated length (2) normal writes might accompany with TruncOp of randomized chosen truncate_size (3) for ReadOp, pick a random 'length' to read, and do checksum simultaneously for the same range ([0, 'length']) to read too. Since the 'length' for reading is randomized chosen, it might exceed the current object size, and hence causing an EOVERFLOW error. Related issues: http://qa-proxy.ceph.com/teuthology/xxg-2017-09-22_01:52:47-rados-wip-object-logic-size-distro-basic-smithi/1657337 http://qa-proxy.ceph.com/teuthology/xxg-2017-09-22_14:14:19-rados-wip-object-logic-size-distro-basic-smithi/1658015 Fix the above problems by keeping pace with normal reads. Signed-off-by: xie xingguo --- src/osd/PrimaryLogPG.cc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc index 6179d63a14c53..facbbd20c754f 100644 --- a/src/osd/PrimaryLogPG.cc +++ b/src/osd/PrimaryLogPG.cc @@ -4410,8 +4410,21 @@ int PrimaryLogPG::do_checksum(OpContext *ctx, OSDOp& osd_op, if (op.checksum.offset == 0 && op.checksum.length == 0) { // zeroed offset+length implies checksum whole object op.checksum.length = oi.size; - } else if (op.checksum.offset + op.checksum.length > oi.size) { - return -EOVERFLOW; + } else if (op.checksum.offset >= oi.size) { + // read size was trimmed to zero, do nothing + // see PrimaryLogPG::do_read + return 0; + } else if (op.extent.offset + op.extent.length > oi.size) { + op.extent.length = oi.size - op.extent.offset; + if (op.checksum.chunk_size > 0 && + op.checksum.length % op.checksum.chunk_size != 0) { + dout(10) << __func__ << ": length (trimmed to 0x" + << std::hex << op.checksum.length + << ") not aligned to chunk size 0x" + << op.checksum.chunk_size << std::dec + << dendl; + return -EINVAL; + } } Checksummer::CSumType csum_type; -- 2.39.5