From: xie xingguo Date: Sun, 24 Sep 2017 00:58:45 +0000 (+0800) Subject: osd/PrimaryLogPG: allow trimmed read for OP_CHECKSUM X-Git-Tag: v13.0.1~728^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=1e4263fa5da0534beb53b6cd0d90b4917f9fcad2;p=ceph.git 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 --- 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;