]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/osd/osd: introduce start_pg_operation
authorSamuel Just <sjust@redhat.com>
Fri, 11 Feb 2022 04:22:56 +0000 (04:22 +0000)
committerSamuel Just <sjust@redhat.com>
Fri, 6 May 2022 02:38:21 +0000 (02:38 +0000)
We're going to unify responsibility for routing requests to requests
to start_pg_operation from the different osd operation types.  Later,
this will move into a new type responsible for dealing with the pg->core
mapping.

Signed-off-by: Samuel Just <sjust@redhat.com>
src/crimson/osd/osd.cc
src/crimson/osd/osd.h
src/crimson/osd/osd_operation.h

index 2c88f5a5de02f23364376c11e07cbd3e379999cc..17339eaddd8dea3dd95b15e7e8514a8499f9b984 100644 (file)
@@ -52,6 +52,7 @@
 #include "crimson/osd/osd_operations/pg_advance_map.h"
 #include "crimson/osd/osd_operations/recovery_subrequest.h"
 #include "crimson/osd/osd_operations/replicated_request.h"
+#include "crimson/osd/osd_operation_external_tracking.h"
 
 namespace {
   seastar::logger& logger() {
index ae0ac9bc0e5947b14e37cd9c7ef89a69cd97f105..a40670fe0f255be559a3f20357e8670c8653505b 100644 (file)
@@ -246,6 +246,67 @@ public:
   Ref<PG> get_pg(spg_t pgid);
   seastar::future<> send_beacon();
 
+  template <typename T, typename... Args>
+  auto start_pg_operation(Args&&... args) {
+    auto op = shard_services.registry.create_operation<T>(
+      std::forward<Args>(args)...);
+    auto &logger = crimson::get_logger(ceph_subsys_osd);
+    logger.debug("{}: starting {}", *op, __func__);
+    auto &opref = *op;
+
+    auto fut = opref.template enter_stage<>(
+      opref.get_connection_pipeline().await_active
+    ).then([this, &opref, &logger] {
+      logger.debug("{}: start_pg_operation in await_active stage", opref);
+      return state.when_active();
+    }).then([&logger, &opref] {
+      logger.debug("{}: start_pg_operation active, entering await_map", opref);
+      return opref.template enter_stage<>(
+       opref.get_connection_pipeline().await_map);
+    }).then([this, &logger, &opref] {
+      logger.debug("{}: start_pg_operation await_map stage", opref);
+      using OSDMapBlockingEvent =
+       OSD_OSDMapGate::OSDMapBlocker::BlockingEvent;
+      return opref.template with_blocking_event<OSDMapBlockingEvent>(
+       [this, &opref](auto &&trigger) {
+         return osdmap_gate.wait_for_map(std::move(trigger),
+                                         opref.get_epoch());
+       });
+    }).then([&logger, &opref](auto epoch) {
+      logger.debug("{}: got map {}, entering get_pg", opref, epoch);
+      return opref.template enter_stage<>(
+       opref.get_connection_pipeline().get_pg);
+    }).then([this, &logger, &opref] {
+      logger.debug("{}: in get_pg", opref);
+      if constexpr (T::can_create()) {
+       logger.debug("{}: can_create", opref);
+       return opref.template with_blocking_event<
+         PGMap::PGCreationBlockingEvent
+         >([this, &opref](auto &&trigger) {
+           std::ignore = this; // avoid clang warning
+           return get_or_create_pg(
+             std::move(trigger),
+             opref.get_pgid(), opref.get_epoch(),
+             std::move(opref.get_create_info()));
+         });
+      } else {
+       logger.debug("{}: !can_create", opref);
+       return opref.template with_blocking_event<
+         PGMap::PGCreationBlockingEvent
+         >([this, &opref](auto &&trigger) {
+           std::ignore = this; // avoid clang warning
+           return wait_for_pg(std::move(trigger), opref.get_pgid());
+         });
+      }
+    }).then([this, &logger, &opref](Ref<PG> pgref) {
+      logger.debug("{}: have_pg", opref);
+      return opref.with_pg(shard_services, pgref);
+    }).then([op] { /* Retain refcount on op until completion */ });
+
+    return std::make_pair(std::move(op), std::move(fut));
+  }
+
+
 private:
   LogClient log_client;
   LogChannelRef clog;
index bbc5600c59c1e75a6f2022cf4203b88197824397..e768503c02b3666434d29784603d5719408e8b5e 100644 (file)
@@ -155,6 +155,10 @@ protected:
 
   template <class OpT>
   friend class crimson::os::seastore::OperationProxyT;
+
+  // OSD::start_pg_operation needs access to enter_stage, we can make this
+  // more sophisticated later on
+  friend class OSD;
 };
 
 /**