From eec27f58326edc81dbd3ca5ee030039d320ab254 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Wed, 18 Sep 2019 22:54:37 +0800 Subject: [PATCH] crimson/osd: handle pg ops with do_pg_ops() currently, OpsExecuter tries to load the object info for all ops to be executed, but the PG ops do not require the existence of object specified by op. so we need to specialize for them. in this change, * `OpsExecuter::execute_pg_op()` is added to handle pg ops without loading object info first. * `pgnls` and `pgnls_filter` are handled by `OpsExecuter::execute_pg_op()`. Signed-off-by: Kefu Chai --- src/crimson/osd/ops_executer.cc | 28 ++++++++++++++++++++-------- src/crimson/osd/ops_executer.h | 4 ++++ src/crimson/osd/pg.cc | 29 ++++++++++++++++++++++++++++- src/crimson/osd/pg.h | 1 + 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/src/crimson/osd/ops_executer.cc b/src/crimson/osd/ops_executer.cc index cd455cdd9d2f9..c49e38bfb17e0 100644 --- a/src/crimson/osd/ops_executer.cc +++ b/src/crimson/osd/ops_executer.cc @@ -386,14 +386,6 @@ OpsExecuter::execute_osd_op(OSDOp& osd_op) return do_write_op([&osd_op] (auto& backend, auto& os, auto& txn) { return backend.setxattr(os, osd_op, txn); }); - case CEPH_OSD_OP_PGNLS_FILTER: - return do_pg_op([&osd_op] (const auto& pg, const auto& nspace) { - return do_pgnls_filtered(pg, nspace, osd_op); - }); - case CEPH_OSD_OP_PGNLS: - return do_pg_op([&osd_op] (const auto& pg, const auto& nspace) { - return do_pgnls(pg, nspace, osd_op); - }); case CEPH_OSD_OP_DELETE: return do_write_op([&osd_op] (auto& backend, auto& os, auto& txn) { return backend.remove(os, txn); @@ -446,4 +438,24 @@ OpsExecuter::execute_osd_op(OSDOp& osd_op) } } +seastar::future<> +OpsExecuter::execute_pg_op(OSDOp& osd_op) +{ + logger().warn("handling op {}", ceph_osd_op_name(osd_op.op.op)); + switch (const ceph_osd_op& op = osd_op.op; op.op) { + case CEPH_OSD_OP_PGNLS: + return do_pg_op([&osd_op] (const auto& pg, const auto& nspace) { + return do_pgnls(pg, nspace, osd_op); + }); + case CEPH_OSD_OP_PGNLS_FILTER: + return do_pg_op([&osd_op] (const auto& pg, const auto& nspace) { + return do_pgnls_filtered(pg, nspace, osd_op); + }); + default: + logger().warn("unknown op {}", ceph_osd_op_name(op.op)); + throw std::runtime_error( + fmt::format("op '{}' not supported", ceph_osd_op_name(op.op))); + } +} + } // namespace ceph::osd diff --git a/src/crimson/osd/ops_executer.h b/src/crimson/osd/ops_executer.h index 81b8d718da52c..61f1d5b73714d 100644 --- a/src/crimson/osd/ops_executer.h +++ b/src/crimson/osd/ops_executer.h @@ -103,8 +103,12 @@ public: backend(pg.get_backend()), msg(std::move(msg)) { } + OpsExecuter(PG& pg, Ref msg) + : OpsExecuter{PGBackend::cached_os_t{}, pg, std::move(msg)} + {} seastar::future<> execute_osd_op(class OSDOp& osd_op); + seastar::future<> execute_pg_op(class OSDOp& osd_op); template seastar::future<> submit_changes(Func&& f) &&; diff --git a/src/crimson/osd/pg.cc b/src/crimson/osd/pg.cc index 33ffb32a0ba8e..e63b2e6fbcff3 100644 --- a/src/crimson/osd/pg.cc +++ b/src/crimson/osd/pg.cc @@ -394,6 +394,28 @@ seastar::future> PG::do_osd_ops(Ref m) }); } +seastar::future> PG::do_pg_ops(Ref m) +{ + return seastar::do_with(OpsExecuter{*this/* as const& */, m}, + [this, m] (auto& ox) { + return seastar::do_for_each(m->ops, [this, &ox](OSDOp& osd_op) { + logger().debug("will be handling pg op {}", ceph_osd_op_name(osd_op.op.op)); + return ox.execute_pg_op(osd_op); + }); + }).then([m, this] { + auto reply = make_message(m.get(), 0, get_osdmap_epoch(), + CEPH_OSD_FLAG_ACK | CEPH_OSD_FLAG_ONDISK, + false); + return seastar::make_ready_future>(std::move(reply)); + }).handle_exception_type([=](const ceph::osd::error& e) { + auto reply = make_message( + m.get(), -e.code().value(), get_osdmap_epoch(), 0, false); + reply->set_enoent_reply_versions(peering_state.get_info().last_update, + peering_state.get_info().last_user_version); + return seastar::make_ready_future>(std::move(reply)); + }); +} + seastar::future<> PG::handle_op(ceph::net::Connection* conn, Ref m) { @@ -401,7 +423,12 @@ seastar::future<> PG::handle_op(ceph::net::Connection* conn, if (m->finish_decode()) { m->clear_payload(); } - return do_osd_ops(m); + if (std::any_of(begin(m->ops), end(m->ops), + [](auto& op) { return ceph_osd_op_type_pg(op.op.op); })) { + return do_pg_ops(m); + } else { + return do_osd_ops(m); + } }).then([conn](Ref reply) { return conn->send(reply); }); diff --git a/src/crimson/osd/pg.h b/src/crimson/osd/pg.h index e6aeff7e72f7b..689d78dd251f6 100644 --- a/src/crimson/osd/pg.h +++ b/src/crimson/osd/pg.h @@ -443,6 +443,7 @@ private: const boost::statechart::event_base &evt, PeeringCtx &rctx); seastar::future> do_osd_ops(Ref m); + seastar::future> do_pg_ops(Ref m); seastar::future<> do_osd_op( ObjectState& os, OSDOp& op, -- 2.39.5