From: Sage Weil Date: Tue, 28 Jan 2020 19:33:49 +0000 (-0600) Subject: osd: dispatch_context and queue split finish on early bail-out X-Git-Tag: v14.2.10~44^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=795262d71aefc26fed5758029cba59ff093b97ab;p=ceph.git osd: dispatch_context and queue split finish on early bail-out If we bail out of advance_pg early because there is an upcoming merge, we still need to dispatch_context() on rctx before we drop the PG lock. And the rctx that we submit needs to include the on_applied finisher comit to call _finish_splits. This is noticeable (at least) when there is a split and merge that are both known. When we process the split, the new child is added to new_pgs. When we get to the merge epoch, we stop early and take the bail-out path. Fix by adding a dispatch_context call for this path. And further make sure that both dispatch_context callers in this function queue up the new_pgs event. Fixes: https://tracker.ceph.com/issues/43825 Signed-off-by: Sage Weil (cherry picked from commit 14c4dbb03fe3c7fb4a0a6fa40dcb89e89fb66b3c) Conflicts: src/osd/OSD.cc - where master says "rctx.transaction.register_on_applied", replaced with nautilus equivalent: "rctx->transaction->register_on_applied" - where master says "dispatch_context(rctx, pg, pg->get_osdmap(), &handle)", replaced with nautilus equivalent: "dispatch_context_transaction(*rctx, pg, &handle)" --- diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 6004119a6966..a963b7fbe186 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -8962,6 +8962,11 @@ bool OSD::advance_pg( << " is merge source, target is " << parent << dendl; pg->write_if_dirty(rctx); + if (!new_pgs.empty()) { + rctx->transaction->register_on_applied(new C_FinishSplits(this, + new_pgs)); + new_pgs.clear(); + } dispatch_context_transaction(*rctx, pg, &handle); pg->ch->flush(); // release backoffs explicitly, since the on_shutdown path @@ -9034,6 +9039,12 @@ bool OSD::advance_pg( } else { dout(20) << __func__ << " not ready to merge yet" << dendl; pg->write_if_dirty(rctx); + if (!new_pgs.empty()) { + rctx->transaction->register_on_applied(new C_FinishSplits(this, + new_pgs)); + new_pgs.clear(); + } + dispatch_context_transaction(*rctx, pg, &handle); pg->unlock(); // kick source(s) to get them ready for (auto& i : children) {