]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/osd: implement cmp-ext op
authorKefu Chai <kchai@redhat.com>
Thu, 20 Aug 2020 17:28:07 +0000 (01:28 +0800)
committerKefu Chai <kchai@redhat.com>
Mon, 24 Aug 2020 09:50:15 +0000 (17:50 +0800)
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 <kchai@redhat.com>
src/crimson/osd/ops_executer.cc
src/crimson/osd/pg_backend.cc
src/crimson/osd/pg_backend.h

index 9616399a95a86cc10d3e09646e81cddb77cbb02d..bf7ea33feb912ad15b0596114e46530b3a3fd36a 100644 (file)
@@ -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);
index 827441efddec94894b6e440fc278ab0ef54cc364..c14c8c52213e858fb38fec2e3ef70e4a42cb05a4 100644 (file)
@@ -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<ceph::bufferlist>();
+  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)
index 6cad22eeb8937933abc90d8c39c75fcb09da719c..8efb012e5150da6445d0caa194c0566c31797d3a 100644 (file)
@@ -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<crimson::ct_error::enoent>;
   stat_errorator::future<> stat(
     const ObjectState& os,