]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson:add OMAP_CMP support
authorChunmei Liu <chunmei.liu@intel.com>
Sat, 19 Mar 2022 09:27:50 +0000 (02:27 -0700)
committerChunmei Liu <chunmei.liu@intel.com>
Wed, 30 Mar 2022 00:38:17 +0000 (17:38 -0700)
Signed-off-by: Chunmei Liu <chunmei.liu@intel.com>
src/crimson/common/errorator.h
src/crimson/osd/ops_executer.cc
src/crimson/osd/ops_executer.h
src/crimson/osd/pg_backend.cc
src/crimson/osd/pg_backend.h

index 8472ad00eedfb7204227324dead4769d1efaa427..0677bd4b3eeb19266c56288f5b4a3ea773ad5f0b 100644 (file)
@@ -1133,6 +1133,7 @@ namespace ct_error {
     ct_error_code<std::errc::file_too_large>;
   using address_in_use = ct_error_code<std::errc::address_in_use>;
   using address_not_available = ct_error_code<std::errc::address_not_available>;
+  using ecanceled = ct_error_code<std::errc::operation_canceled>;
 
   struct pass_further_all {
     template <class ErrorT>
index fe12d2af9a587a9f89883f55f4bc160dc12ea511..170d091299c4a85ee9112cd7f0a44fddc27ad022 100644 (file)
@@ -581,6 +581,10 @@ OpsExecuter::execute_op(OSDOp& osd_op)
     return do_read_op([this, &osd_op] (auto& backend, const auto& os) {
       return backend.omap_get_vals(os, osd_op, delta_stats);
     });
+  case CEPH_OSD_OP_OMAP_CMP:
+    return  do_read_op([this, &osd_op] (auto& backend, const auto& os) {
+      return backend.omap_cmp(os, osd_op, delta_stats);
+    });
   case CEPH_OSD_OP_OMAPGETHEADER:
     return do_read_op([this, &osd_op] (auto& backend, const auto& os) {
       return backend.omap_get_header(os, osd_op, delta_stats);
index 6714bb69256ea2abdd41e17639a3cda629895b39..8e4420bb86bb7a0bf01bc3013d9d548942a40320 100644 (file)
@@ -42,6 +42,7 @@ class OpsExecuter : public seastar::enable_lw_shared_from_this<OpsExecuter> {
     crimson::ct_error::enoent,
     crimson::ct_error::invarg,
     crimson::ct_error::erange,
+    crimson::ct_error::ecanceled,
     crimson::ct_error::permission_denied,
     crimson::ct_error::operation_not_supported,
     crimson::ct_error::input_output_error,
index 29f09b69e8432ddc3f9b3bc8361b13b8c696d64d..c71cb661fe19dd966dbcc456a2412a2dffcf42c6 100644 (file)
@@ -1163,7 +1163,72 @@ PGBackend::omap_get_keys(
       ll_read_errorator::pass_further{}
     );
 }
+static
+PGBackend::omap_cmp_ertr::future<> do_omap_val_cmp(
+  std::map<std::string, bufferlist, std::less<>> out,
+  std::map<std::string, std::pair<bufferlist, int>> assertions)
+{
+  bufferlist empty;
+  for (const auto &[akey, avalue] : assertions) {
+    const auto [abl, aflag] = avalue;
+    auto out_entry = out.find(akey);
+    bufferlist &bl = (out_entry != out.end()) ? out_entry->second : empty;
+    switch (aflag) {
+      case CEPH_OSD_CMPXATTR_OP_EQ:
+        if (!(bl == abl)) {
+          return crimson::ct_error::ecanceled::make();
+        }
+      break;
+      case CEPH_OSD_CMPXATTR_OP_LT:
+        if (!(bl < abl)) {
+          return crimson::ct_error::ecanceled::make();
+        }
+      break;
+      case CEPH_OSD_CMPXATTR_OP_GT:
+        if (!(bl > abl)) {
+          return crimson::ct_error::ecanceled::make();
+        }
+      break;
+      default:
+        return crimson::ct_error::invarg::make();
+    }
+  }
+  return PGBackend::omap_cmp_ertr::now();
+}
+PGBackend::omap_cmp_iertr::future<>
+PGBackend::omap_cmp(
+  const ObjectState& os,
+  OSDOp& osd_op,
+  object_stat_sum_t& delta_stats) const
+{
+  if (!os.exists || os.oi.is_whiteout()) {
+    logger().debug("{}: object does not exist: {}", os.oi.soid);
+    return crimson::ct_error::enoent::make();
+  }
 
+  auto bp = osd_op.indata.cbegin();
+  std::map<std::string, std::pair<bufferlist, int> > assertions;
+  try {
+    decode(assertions, bp);
+  } catch (buffer::error&) {
+    return crimson::ct_error::invarg::make();
+  }
+
+  delta_stats.num_rd++;
+  if (os.oi.is_omap()) {
+    std::set<std::string> to_get;
+    for (auto &i: assertions) {
+      to_get.insert(i.first);
+    }
+    return store->omap_get_values(coll, ghobject_t{os.oi.soid}, to_get)
+      .safe_then([=, &osd_op] (auto&& out) -> omap_cmp_iertr::future<> {
+      osd_op.rval = 0;
+      return  do_omap_val_cmp(out, assertions);
+    });
+  } else {
+    return crimson::ct_error::ecanceled::make();
+  }
+}
 PGBackend::ll_read_ierrorator::future<>
 PGBackend::omap_get_vals(
   const ObjectState& os,
@@ -1174,6 +1239,10 @@ PGBackend::omap_get_vals(
     throw crimson::common::system_shutdown_exception();
   }
 
+  if (!os.exists || os.oi.is_whiteout()) {
+    logger().debug("{}: object does not exist: {}", os.oi.soid);
+    return crimson::ct_error::enoent::make();
+  }
   std::string start_after;
   uint64_t max_return;
   std::string filter_prefix;
index 563638ff06dc746ca8e4230857aec4c13c27e80f..aa2fcee672ac89c565647fc0dad82ee25f4388d6 100644 (file)
@@ -250,6 +250,18 @@ public:
     const ObjectState& os,
     OSDOp& osd_op,
     object_stat_sum_t& delta_stats) const;
+  using omap_cmp_ertr =
+    crimson::os::FuturizedStore::read_errorator::extend<
+      crimson::ct_error::ecanceled,
+      crimson::ct_error::invarg>;
+  using omap_cmp_iertr =
+    ::crimson::interruptible::interruptible_errorator<
+      ::crimson::osd::IOInterruptCondition,
+      omap_cmp_ertr>;
+  omap_cmp_iertr::future<> omap_cmp(
+    const ObjectState& os,
+    OSDOp& osd_op,
+    object_stat_sum_t& delta_stats) const;
   ll_read_ierrorator::future<> omap_get_vals(
     const ObjectState& os,
     OSDOp& osd_op,