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>
{
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)