]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/osd: wake pgs_creating waiters in PGMap::pg_loaded() 69019/head
authorKefu Chai <k.chai@proxmox.com>
Wed, 20 May 2026 02:22:24 +0000 (10:22 +0800)
committerKefu Chai <k.chai@proxmox.com>
Wed, 20 May 2026 11:29:48 +0000 (19:29 +0800)
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 <k.chai@proxmox.com>
src/crimson/osd/pg_map.cc

index 6c6552f07cdea7a5ea3201c9eb23d225d9e6225d..3fce70fe9cba6d9a513f034601d7719150d2732f 100644 (file)
@@ -328,6 +328,16 @@ void PGMap::pg_loaded(spg_t pgid, Ref<PG> 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)