From df3e1e635238c90a5242c5334abd8e5eed28b8a0 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Wed, 20 May 2026 10:22:24 +0800 Subject: [PATCH] crimson/osd: wake pgs_creating waiters in PGMap::pg_loaded() wait_for_pg() parks callers on pgs_creating[pgid] when the PG isn't in pgs yet. pg_created() wakes those waiters; pg_loaded() didn't. An op that races ahead of a PG load hangs indefinitely at CreateOrWaitPG. Add the symmetric wake-up in pg_loaded() with a conditional find -- unlike pg_created(), a loaded PG may have no waiters at all. See-also: e6c6de335b6a Signed-off-by: Kefu Chai --- src/crimson/osd/pg_map.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/crimson/osd/pg_map.cc b/src/crimson/osd/pg_map.cc index 6c6552f07cd..3fce70fe9cb 100644 --- a/src/crimson/osd/pg_map.cc +++ b/src/crimson/osd/pg_map.cc @@ -328,6 +328,16 @@ void PGMap::pg_loaded(spg_t pgid, Ref pg) { ceph_assert(!pgs.count(pgid)); pgs.emplace(pgid, pg); + // An op may have called wait_for_pg() before this PG finished loading + // from local store, parking on pgs_creating[pgid].promise. Wake any + // such waiters now -- pg_created() does the same on the create path, + // but the load path was missing the symmetric notification. + if (auto creating_iter = pgs_creating.find(pgid); + creating_iter != pgs_creating.end()) { + auto promise = std::move(creating_iter->second.promise); + pgs_creating.erase(creating_iter); + promise.set_value(pg); + } } void PGMap::pg_creation_canceled(spg_t pgid) -- 2.47.3