From: Kefu Chai Date: Wed, 18 Sep 2019 14:54:37 +0000 (+0800) Subject: crimson/osd: handle pg ops with do_pg_ops() X-Git-Tag: v15.1.0~1510^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=eec27f58326edc81dbd3ca5ee030039d320ab254;p=ceph.git 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 --- diff --git a/src/crimson/osd/ops_executer.cc b/src/crimson/osd/ops_executer.cc index cd455cdd9d2f..c49e38bfb17e 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 81b8d718da52..61f1d5b73714 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 33ffb32a0ba8..e63b2e6fbcff 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 e6aeff7e72f7..689d78dd251f 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,