]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/osd: notify waiters if pool for creating pg does not exist 48352/head
authorSamuel Just <sjust@redhat.com>
Sat, 1 Oct 2022 19:43:13 +0000 (12:43 -0700)
committerSamuel Just <sjust@redhat.com>
Wed, 5 Oct 2022 05:08:55 +0000 (22:08 -0700)
Fixes: https://tracker.ceph.com/issues/57740
Signed-off-by: Samuel Just <sjust@redhat.com>
src/crimson/osd/pg_map.cc
src/crimson/osd/pg_map.h
src/crimson/osd/pg_shard_manager.h
src/crimson/osd/shard_services.cc
src/crimson/osd/shard_services.h

index 8a6e5995daf2c8676dc4bdb9865dcb5d73352e22..b663d02dd9213da7c17cbea027f3d4968a15c82e 100644 (file)
@@ -25,17 +25,19 @@ void PGMap::PGCreationState::dump_detail(Formatter *f) const
   f->dump_bool("creating", creating);
 }
 
-std::pair<seastar::future<Ref<PG>>, bool>
+PGMap::wait_for_pg_ret
 PGMap::wait_for_pg(PGCreationBlockingEvent::TriggerI&& trigger, spg_t pgid)
 {
   if (auto pg = get_pg(pgid)) {
-    return make_pair(seastar::make_ready_future<Ref<PG>>(pg), true);
+    return make_pair(
+      wait_for_pg_fut(wait_for_pg_ertr::ready_future_marker{}, pg),
+      true);
   } else {
     auto &state = pgs_creating.emplace(pgid, pgid).first->second;
     return make_pair(
-      // TODO: add to blocker Trigger-taking make_blocking_future
-      trigger.maybe_record_blocking(state.promise.get_shared_future(), state),
-      state.creating);
+      wait_for_pg_fut(
+       trigger.maybe_record_blocking(state.promise.get_shared_future(), state)
+      ), state.creating);
   }
 }
 
@@ -77,6 +79,20 @@ void PGMap::pg_loaded(spg_t pgid, Ref<PG> pg)
   pgs.emplace(pgid, pg);
 }
 
+void PGMap::pg_creation_canceled(spg_t pgid)
+{
+  logger().debug("PGMap::pg_creation_canceled: {}", pgid);
+  ceph_assert(!pgs.count(pgid));
+
+  auto creating_iter = pgs_creating.find(pgid);
+  ceph_assert(creating_iter != pgs_creating.end());
+  auto promise = std::move(creating_iter->second.promise);
+  pgs_creating.erase(creating_iter);
+  promise.set_exception(
+    crimson::ct_error::ecanceled::exception_ptr()
+  );
+}
+
 PGMap::~PGMap() {}
 
 }
index 95b9a5075e0cfbb4a8d0b6e6df07e87c84d9f50c..ed753749a55e883f0e563a17b0fa1a63a6666e9c 100644 (file)
@@ -123,8 +123,11 @@ public:
    * Get future for pg with a bool indicating whether it's already being
    * created.
    */
-  std::pair<seastar::future<Ref<PG>>, bool>
-  wait_for_pg(PGCreationBlockingEvent::TriggerI&&, spg_t pgid);
+  using wait_for_pg_ertr = crimson::errorator<
+    crimson::ct_error::ecanceled>;
+  using wait_for_pg_fut = wait_for_pg_ertr::future<Ref<PG>>;
+  using wait_for_pg_ret = std::pair<wait_for_pg_fut, bool>;
+  wait_for_pg_ret wait_for_pg(PGCreationBlockingEvent::TriggerI&&, spg_t pgid);
 
   /**
    * get PG in non-blocking manner
@@ -146,6 +149,11 @@ public:
    */
   void pg_loaded(spg_t pgid, Ref<PG> pg);
 
+  /**
+   * Cancel pending creation of pgid.
+   */
+  void pg_creation_canceled(spg_t pgid);
+
   pgs_t& get_pgs() { return pgs; }
   const pgs_t& get_pgs() const { return pgs; }
   auto get_pg_count() const { return pgs.size(); }
index 37b98795a8ec5be1a702e712cdf514567df86d5a..b1c4ae0fc0c0bebfcea9769a3159c0df2422f60c 100644 (file)
@@ -178,11 +178,17 @@ public:
            return shard_services.get_or_create_pg(
              std::move(trigger),
              opref.get_pgid(), opref.get_epoch(),
-             std::move(opref.get_create_info()));
-         }).then([&logger, &shard_services, &opref](Ref<PG> pgref) {
+             std::move(opref.get_create_info())
+           );
+         }).safe_then([&logger, &shard_services, &opref](Ref<PG> pgref) {
            logger.debug("{}: have_pg", opref);
            return opref.with_pg(shard_services, pgref);
-         }).then([op=std::move(op)] {});
+         }).handle_error(
+           crimson::ct_error::ecanceled::handle([&logger, &opref](auto) {
+             logger.debug("{}: pg creation canceled, dropping", opref);
+             return seastar::now();
+           })
+         ).then([op=std::move(op)] {});
       });
   }
 
@@ -215,10 +221,15 @@ public:
              auto &&trigger) {
            return shard_services.wait_for_pg(
              std::move(trigger), opref.get_pgid());
-         }).then([&logger, &shard_services, &opref](Ref<PG> pgref) {
+         }).safe_then([&logger, &shard_services, &opref](Ref<PG> pgref) {
            logger.debug("{}: have_pg", opref);
            return opref.with_pg(shard_services, pgref);
-         }).then([op=std::move(op)] {});
+         }).handle_error(
+           crimson::ct_error::ecanceled::handle([&logger, &opref](auto) {
+             logger.debug("{}: pg creation canceled, dropping", opref);
+             return seastar::now();
+           })
+         ).then([op=std::move(op)] {});
       });
   }
 
index 68794184d0a540c2dbf6690db66cde260460da44..ae21c3fe5cd25c3ca591f8ac1bb6e2eee6391d28 100644 (file)
@@ -499,6 +499,7 @@ seastar::future<Ref<PG>> ShardServices::handle_pg_create_info(
                "{} ignoring pgid {}, pool dne",
                __func__,
                pgid);
+             local_state.pg_map.pg_creation_canceled(pgid);
              return seastar::make_ready_future<
                std::tuple<Ref<PG>, OSDMapService::cached_map_t>
                >(std::make_tuple(Ref<PG>(), startmap));
@@ -513,6 +514,7 @@ seastar::future<Ref<PG>> ShardServices::handle_pg_create_info(
                "{} dropping {} create, pool does not have CREATING flag set",
                __func__,
                pgid);
+             local_state.pg_map.pg_creation_canceled(pgid);
              return seastar::make_ready_future<
                std::tuple<Ref<PG>, OSDMapService::cached_map_t>
                >(std::make_tuple(Ref<PG>(), startmap));
@@ -571,7 +573,7 @@ seastar::future<Ref<PG>> ShardServices::handle_pg_create_info(
 }
 
 
-seastar::future<Ref<PG>>
+ShardServices::get_or_create_pg_ret
 ShardServices::get_or_create_pg(
   PGMap::PGCreationBlockingEvent::TriggerI&& trigger,
   spg_t pgid,
@@ -588,12 +590,14 @@ ShardServices::get_or_create_pg(
     }
     return std::move(fut);
   } else {
-    return seastar::make_ready_future<Ref<PG>>(
+    return get_or_create_pg_ret(
+      get_or_create_pg_ertr::ready_future_marker{},
       local_state.pg_map.get_pg(pgid));
   }
 }
 
-seastar::future<Ref<PG>> ShardServices::wait_for_pg(
+ShardServices::wait_for_pg_ret
+ShardServices::wait_for_pg(
   PGMap::PGCreationBlockingEvent::TriggerI&& trigger, spg_t pgid)
 {
   return local_state.pg_map.wait_for_pg(std::move(trigger), pgid).first;
index 2f6e026b342d3d850fb0d13bd420362502d84473..e51038d72bce38fee5a7ccc55270489e961304fb 100644 (file)
@@ -375,12 +375,18 @@ public:
     bool do_create);
   seastar::future<Ref<PG>> handle_pg_create_info(
     std::unique_ptr<PGCreateInfo> info);
-  seastar::future<Ref<PG>> get_or_create_pg(
+
+  using get_or_create_pg_ertr = PGMap::wait_for_pg_ertr;
+  using get_or_create_pg_ret = get_or_create_pg_ertr::future<Ref<PG>>;
+  get_or_create_pg_ret get_or_create_pg(
     PGMap::PGCreationBlockingEvent::TriggerI&&,
     spg_t pgid,
     epoch_t epoch,
     std::unique_ptr<PGCreateInfo> info);
-  seastar::future<Ref<PG>> wait_for_pg(
+
+  using wait_for_pg_ertr = PGMap::wait_for_pg_ertr;
+  using wait_for_pg_ret = wait_for_pg_ertr::future<Ref<PG>>;
+  wait_for_pg_ret wait_for_pg(
     PGMap::PGCreationBlockingEvent::TriggerI&&, spg_t pgid);
   seastar::future<Ref<PG>> load_pg(spg_t pgid);