From 5313440847ebff9600f8b8340de4858f915e8be0 Mon Sep 17 00:00:00 2001 From: chunmei-liu Date: Fri, 25 Jun 2021 22:06:54 -0700 Subject: [PATCH] crimson: add cmp_xatt support fix Exceptional future ignored: std::runtime_error (op 'cmpxattr' not supported) Signed-off-by: chunmei-liu --- src/crimson/osd/ops_executer.cc | 4 ++ src/crimson/osd/pg_backend.cc | 101 ++++++++++++++++++++++++++++++++ src/crimson/osd/pg_backend.h | 10 ++++ 3 files changed, 115 insertions(+) diff --git a/src/crimson/osd/ops_executer.cc b/src/crimson/osd/ops_executer.cc index 4bc876c00baa3..c0d2e7f3e9669 100644 --- a/src/crimson/osd/ops_executer.cc +++ b/src/crimson/osd/ops_executer.cc @@ -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) { diff --git a/src/crimson/osd/pg_backend.cc b/src/crimson/osd/pg_backend.cc index 14546b83195b1..f9f869478b08d 100644 --- a/src/crimson/osd/pg_backend.cc +++ b/src/crimson/osd/pg_backend.cc @@ -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( diff --git a/src/crimson/osd/pg_backend.h b/src/crimson/osd/pg_backend.h index 699bad16167dc..4edee07a57816 100644 --- a/src/crimson/osd/pg_backend.h +++ b/src/crimson/osd/pg_backend.h @@ -9,6 +9,8 @@ #include #include +#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; using rm_xattr_iertr = ::crimson::interruptible::interruptible_errorator< -- 2.39.5