From 3414b2827840d992bfd76acdbcb93c84d755972c Mon Sep 17 00:00:00 2001 From: Chunmei Liu Date: Sat, 19 Mar 2022 02:27:50 -0700 Subject: [PATCH] crimson:add OMAP_CMP support Signed-off-by: Chunmei Liu --- src/crimson/common/errorator.h | 1 + src/crimson/osd/ops_executer.cc | 4 ++ src/crimson/osd/ops_executer.h | 1 + src/crimson/osd/pg_backend.cc | 69 +++++++++++++++++++++++++++++++++ src/crimson/osd/pg_backend.h | 12 ++++++ 5 files changed, 87 insertions(+) diff --git a/src/crimson/common/errorator.h b/src/crimson/common/errorator.h index 8472ad00eedfb..0677bd4b3eeb1 100644 --- a/src/crimson/common/errorator.h +++ b/src/crimson/common/errorator.h @@ -1133,6 +1133,7 @@ namespace ct_error { ct_error_code; using address_in_use = ct_error_code; using address_not_available = ct_error_code; + using ecanceled = ct_error_code; struct pass_further_all { template diff --git a/src/crimson/osd/ops_executer.cc b/src/crimson/osd/ops_executer.cc index fe12d2af9a587..170d091299c4a 100644 --- a/src/crimson/osd/ops_executer.cc +++ b/src/crimson/osd/ops_executer.cc @@ -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); diff --git a/src/crimson/osd/ops_executer.h b/src/crimson/osd/ops_executer.h index 6714bb69256ea..8e4420bb86bb7 100644 --- a/src/crimson/osd/ops_executer.h +++ b/src/crimson/osd/ops_executer.h @@ -42,6 +42,7 @@ class OpsExecuter : public seastar::enable_lw_shared_from_this { 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, diff --git a/src/crimson/osd/pg_backend.cc b/src/crimson/osd/pg_backend.cc index 29f09b69e8432..c71cb661fe19d 100644 --- a/src/crimson/osd/pg_backend.cc +++ b/src/crimson/osd/pg_backend.cc @@ -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> out, + std::map> 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 > 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 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; diff --git a/src/crimson/osd/pg_backend.h b/src/crimson/osd/pg_backend.h index 563638ff06dc7..aa2fcee672ac8 100644 --- a/src/crimson/osd/pg_backend.h +++ b/src/crimson/osd/pg_backend.h @@ -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, -- 2.39.5