]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson: add cmp_xatt support 42039/head
authorchunmei-liu <chunmei.liu@intel.com>
Sat, 26 Jun 2021 05:06:54 +0000 (22:06 -0700)
committerchunmei-liu <chunmei.liu@intel.com>
Tue, 29 Jun 2021 04:57:47 +0000 (21:57 -0700)
fix Exceptional future ignored: std::runtime_error (op 'cmpxattr' not supported)

Signed-off-by: chunmei-liu <chunmei.liu@intel.com>
src/crimson/osd/ops_executer.cc
src/crimson/osd/pg_backend.cc
src/crimson/osd/pg_backend.h

index 4bc876c00baa38fd63bb12c692f7043701884a10..c0d2e7f3e9669d26e356a58f52756cc89a2a0ca1 100644 (file)
@@ -460,6 +460,10 @@ OpsExecuter::execute_op(OSDOp& osd_op)
     return do_read_op([&osd_op] (auto& backend, const auto& os) {
       return backend.get_xattrs(os, osd_op);
     });
+  case CEPH_OSD_OP_CMPXATTR:
+    return do_read_op([&osd_op] (auto& backend, const auto& os) {
+      return backend.cmp_xattr(os, osd_op);
+    });
   case CEPH_OSD_OP_RMXATTR:
     return do_write_op(
       [&osd_op] (auto& backend, auto& os, auto& txn) {
index 14546b83195b110cf9a0d410f419a370f7c48b92..f9f869478b08d6b9e5f898e1ab3592f686abbda4 100644 (file)
@@ -830,6 +830,107 @@ PGBackend::get_attr_ierrorator::future<> PGBackend::get_xattrs(
     return get_attr_errorator::now();
   });
 }
+static int do_xattr_cmp_str(int op, const string& lhs, bufferlist& rhs_xattr)
+{
+  string rhs(rhs_xattr.c_str(), rhs_xattr.length());
+
+  logger().debug("do_xattr_cmp_str '{}' vs '{}' op {}", lhs, rhs, op);
+
+  switch (op) {
+  case CEPH_OSD_CMPXATTR_OP_EQ:
+    return (lhs.compare(rhs) == 0);
+  case CEPH_OSD_CMPXATTR_OP_NE:
+    return (lhs.compare(rhs) != 0);
+  case CEPH_OSD_CMPXATTR_OP_GT:
+    return (lhs.compare(rhs) > 0);
+  case CEPH_OSD_CMPXATTR_OP_GTE:
+    return (lhs.compare(rhs) >= 0);
+  case CEPH_OSD_CMPXATTR_OP_LT:
+    return (lhs.compare(rhs) < 0);
+  case CEPH_OSD_CMPXATTR_OP_LTE:
+    return (lhs.compare(rhs) <= 0);
+  default:
+    return -EINVAL;
+  }
+}
+
+static int do_xattr_cmp_u64(int op, uint64_t lhs, bufferlist& rhs_xattr)
+{
+  uint64_t rhs;
+
+  if (rhs_xattr.length() > 0) {
+    std::from_chars(rhs_xattr.c_str(), rhs_xattr.c_str() + rhs_xattr.length(), rhs);
+  } else {
+    rhs = 0;
+  }
+  logger().debug("do_xattr_cmp_u64 '{}' vs '{}' op {}", lhs, rhs, op);
+
+  switch (op) {
+  case CEPH_OSD_CMPXATTR_OP_EQ:
+    return (lhs == rhs);
+  case CEPH_OSD_CMPXATTR_OP_NE:
+    return (lhs != rhs);
+  case CEPH_OSD_CMPXATTR_OP_GT:
+    return (lhs > rhs);
+  case CEPH_OSD_CMPXATTR_OP_GTE:
+    return (lhs >= rhs);
+  case CEPH_OSD_CMPXATTR_OP_LT:
+    return (lhs < rhs);
+  case CEPH_OSD_CMPXATTR_OP_LTE:
+    return (lhs <= rhs);
+  default:
+    return -EINVAL;
+  }
+}
+PGBackend::cmp_xattr_ierrorator::future<> PGBackend::cmp_xattr(
+  const ObjectState& os,
+  OSDOp& osd_op) const
+{
+  std::string name{"_"};
+  auto bp = osd_op.indata.cbegin();
+  bp.copy(osd_op.op.xattr.name_len, name);
+  logger().debug("cmpxattr on obj={} for attr={}", os.oi.soid, name);
+  return getxattr(os.oi.soid, name).safe_then_interruptible(
+    [&osd_op] (auto &&xattr) {
+    int result = 0;
+    auto bp = osd_op.indata.cbegin();
+    bp += osd_op.op.xattr.name_len;
+
+    switch (osd_op.op.xattr.cmp_mode) {
+    case CEPH_OSD_CMPXATTR_MODE_STRING:
+      {
+        string val;
+        bp.copy(osd_op.op.xattr.value_len, val);
+        result = do_xattr_cmp_str(osd_op.op.xattr.cmp_op, val, xattr);
+        logger().debug("cmpxattr val={}, xattr= {}", val, xattr);
+      }
+    break;
+    case CEPH_OSD_CMPXATTR_MODE_U64:
+      {
+        uint64_t val;
+        try {
+          decode(val, bp);
+       } catch (ceph::buffer::error& e) {
+          logger().info("cmp_xattr: buffer error expection");
+          result = -EINVAL;
+          break;
+       }
+        result = do_xattr_cmp_u64(osd_op.op.xattr.cmp_op, val, xattr);
+      }
+    break;
+    default:
+      logger().info("bad cmp mode {}", osd_op.op.xattr.cmp_mode);
+      result = -EINVAL;
+    }
+    if (result == 0) {
+      logger().info("cmp_xattr: comparison returned false");
+      osd_op.rval = -ECANCELED;
+    } else {
+      osd_op.rval = result;
+    }
+  });
+}
 
 PGBackend::rm_xattr_iertr::future<>
 PGBackend::rm_xattr(
index 699bad16167dcc7070bced44f278fba729663953..4edee07a578163f4e5e51083aeedc2983aacc241 100644 (file)
@@ -9,6 +9,8 @@
 #include <boost/smart_ptr/local_shared_ptr.hpp>
 #include <boost/container/flat_set.hpp>
 
+#include "include/rados.h"
+
 #include "crimson/os/futurized_store.h"
 #include "crimson/os/futurized_collection.h"
 #include "crimson/osd/acked_peers.h"
@@ -190,6 +192,14 @@ public:
   get_attr_ierrorator::future<> get_xattrs(
     const ObjectState& os,
     OSDOp& osd_op) const;
+  using cmp_xattr_errorator = ::crimson::os::FuturizedStore::get_attr_errorator;
+  using cmp_xattr_ierrorator =
+    ::crimson::interruptible::interruptible_errorator<
+      ::crimson::osd::IOInterruptCondition,
+      cmp_xattr_errorator>;
+  cmp_xattr_ierrorator::future<> cmp_xattr(
+    const ObjectState& os,
+    OSDOp& osd_op) const;
   using rm_xattr_ertr = crimson::errorator<crimson::ct_error::enoent>;
   using rm_xattr_iertr =
     ::crimson::interruptible::interruptible_errorator<