From: Samuel Just Date: Sat, 1 Oct 2022 19:43:13 +0000 (-0700) Subject: crimson/osd: notify waiters if pool for creating pg does not exist X-Git-Tag: v18.1.0~1069^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F48352%2Fhead;p=ceph.git crimson/osd: notify waiters if pool for creating pg does not exist Fixes: https://tracker.ceph.com/issues/57740 Signed-off-by: Samuel Just --- diff --git a/src/crimson/osd/pg_map.cc b/src/crimson/osd/pg_map.cc index 8a6e5995daf2..b663d02dd921 100644 --- a/src/crimson/osd/pg_map.cc +++ b/src/crimson/osd/pg_map.cc @@ -25,17 +25,19 @@ void PGMap::PGCreationState::dump_detail(Formatter *f) const f->dump_bool("creating", creating); } -std::pair>, 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>(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) 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() {} } diff --git a/src/crimson/osd/pg_map.h b/src/crimson/osd/pg_map.h index 95b9a5075e0c..ed753749a55e 100644 --- a/src/crimson/osd/pg_map.h +++ b/src/crimson/osd/pg_map.h @@ -123,8 +123,11 @@ public: * Get future for pg with a bool indicating whether it's already being * created. */ - std::pair>, 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>; + using wait_for_pg_ret = std::pair; + 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); + /** + * 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(); } diff --git a/src/crimson/osd/pg_shard_manager.h b/src/crimson/osd/pg_shard_manager.h index 37b98795a8ec..b1c4ae0fc0c0 100644 --- a/src/crimson/osd/pg_shard_manager.h +++ b/src/crimson/osd/pg_shard_manager.h @@ -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 pgref) { + std::move(opref.get_create_info()) + ); + }).safe_then([&logger, &shard_services, &opref](Ref 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 pgref) { + }).safe_then([&logger, &shard_services, &opref](Ref 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)] {}); }); } diff --git a/src/crimson/osd/shard_services.cc b/src/crimson/osd/shard_services.cc index 68794184d0a5..ae21c3fe5cd2 100644 --- a/src/crimson/osd/shard_services.cc +++ b/src/crimson/osd/shard_services.cc @@ -499,6 +499,7 @@ seastar::future> 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, OSDMapService::cached_map_t> >(std::make_tuple(Ref(), startmap)); @@ -513,6 +514,7 @@ seastar::future> 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, OSDMapService::cached_map_t> >(std::make_tuple(Ref(), startmap)); @@ -571,7 +573,7 @@ seastar::future> ShardServices::handle_pg_create_info( } -seastar::future> +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>( + return get_or_create_pg_ret( + get_or_create_pg_ertr::ready_future_marker{}, local_state.pg_map.get_pg(pgid)); } } -seastar::future> 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; diff --git a/src/crimson/osd/shard_services.h b/src/crimson/osd/shard_services.h index 2f6e026b342d..e51038d72bce 100644 --- a/src/crimson/osd/shard_services.h +++ b/src/crimson/osd/shard_services.h @@ -375,12 +375,18 @@ public: bool do_create); seastar::future> handle_pg_create_info( std::unique_ptr info); - seastar::future> 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>; + get_or_create_pg_ret get_or_create_pg( PGMap::PGCreationBlockingEvent::TriggerI&&, spg_t pgid, epoch_t epoch, std::unique_ptr info); - seastar::future> wait_for_pg( + + using wait_for_pg_ertr = PGMap::wait_for_pg_ertr; + using wait_for_pg_ret = wait_for_pg_ertr::future>; + wait_for_pg_ret wait_for_pg( PGMap::PGCreationBlockingEvent::TriggerI&&, spg_t pgid); seastar::future> load_pg(spg_t pgid);