From: Kefu Chai Date: Thu, 20 Aug 2020 17:28:07 +0000 (+0800) Subject: crimson/osd: implement cmp-ext op X-Git-Tag: v16.1.0~1347^2~9 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=570342b1a92f0ab22f9e3ba33863080f4e771c39;p=ceph.git crimson/osd: implement cmp-ext op it is tested by test_rados.py:TestIoctx.test_cmpext, so let's support this op in crimson as well. Signed-off-by: Kefu Chai --- diff --git a/src/crimson/osd/ops_executer.cc b/src/crimson/osd/ops_executer.cc index 9616399a95a8..bf7ea33feb91 100644 --- a/src/crimson/osd/ops_executer.cc +++ b/src/crimson/osd/ops_executer.cc @@ -455,6 +455,10 @@ OpsExecuter::execute_op(OSDOp& osd_op) return do_read_op([&osd_op] (auto& backend, const auto& os) { return backend.checksum(os, osd_op); }); + case CEPH_OSD_OP_CMPEXT: + return do_read_op([&osd_op] (auto& backend, const auto& os) { + return backend.cmp_ext(os, osd_op); + }); case CEPH_OSD_OP_GETXATTR: return do_read_op([&osd_op] (auto& backend, const auto& os) { return backend.getxattr(os, osd_op); diff --git a/src/crimson/osd/pg_backend.cc b/src/crimson/osd/pg_backend.cc index 827441efddec..c14c8c52213e 100644 --- a/src/crimson/osd/pg_backend.cc +++ b/src/crimson/osd/pg_backend.cc @@ -342,6 +342,52 @@ PGBackend::checksum(const ObjectState& os, OSDOp& osd_op) }); } +PGBackend::cmp_ext_errorator::future<> +PGBackend::cmp_ext(const ObjectState& os, OSDOp& osd_op) +{ + const ceph_osd_op& op = osd_op.op; + // return the index of the first unmatched byte in the payload, hence the + // strange limit and check + if (op.extent.length > MAX_ERRNO) { + return crimson::ct_error::invarg::make(); + } + uint64_t obj_size = os.oi.size; + if (os.oi.truncate_seq < op.extent.truncate_seq && + op.extent.offset + op.extent.length > op.extent.truncate_size) { + obj_size = op.extent.truncate_size; + } + uint64_t ext_len; + if (op.extent.offset >= obj_size) { + ext_len = 0; + } else if (op.extent.offset + op.extent.length > obj_size) { + ext_len = obj_size - op.extent.offset; + } else { + ext_len = op.extent.length; + } + auto read_ext = ll_read_errorator::make_ready_future(); + if (ext_len == 0) { + logger().debug("{}: zero length extent", __func__); + } else if (!os.exists || os.oi.is_whiteout()) { + logger().debug("{}: {} DNE", __func__, os.oi.soid); + } else { + read_ext = _read(os.oi.soid, op.extent.offset, ext_len, 0); + } + return read_ext.safe_then([&osd_op](auto&& read_bl) { + int32_t retcode = 0; + for (unsigned index = 0; index < osd_op.indata.length(); index++) { + char byte_in_op = osd_op.indata[index]; + char byte_from_disk = (index < read_bl.length() ? read_bl[index] : 0); + if (byte_in_op != byte_from_disk) { + logger().debug("cmp_ext: mismatch at {}", index); + retcode = -MAX_ERRNO - index; + break; + } + } + logger().debug("cmp_ext: {}", retcode); + osd_op.rval = retcode; + }); +} + PGBackend::stat_errorator::future<> PGBackend::stat( const ObjectState& os, OSDOp& osd_op) diff --git a/src/crimson/osd/pg_backend.h b/src/crimson/osd/pg_backend.h index 6cad22eeb893..8efb012e5150 100644 --- a/src/crimson/osd/pg_backend.h +++ b/src/crimson/osd/pg_backend.h @@ -65,14 +65,17 @@ public: read_errorator::future<> sparse_read( const ObjectState& os, OSDOp& osd_op); - using checksum_errorator = ll_read_errorator::extend< crimson::ct_error::object_corrupted, crimson::ct_error::invarg>; checksum_errorator::future<> checksum( const ObjectState& os, OSDOp& osd_op); - + using cmp_ext_errorator = ll_read_errorator::extend< + crimson::ct_error::invarg>; + cmp_ext_errorator::future<> cmp_ext( + const ObjectState& os, + OSDOp& osd_op); using stat_errorator = crimson::errorator; stat_errorator::future<> stat( const ObjectState& os,