From 14c4dbb03fe3c7fb4a0a6fa40dcb89e89fb66b3c Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 28 Jan 2020 13:33:49 -0600 Subject: [PATCH] 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 --- src/osd/OSD.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index c7eab558789..6d711900874 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -8465,6 +8465,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(rctx, pg, pg->get_osdmap(), &handle); pg->ch->flush(); // release backoffs explicitly, since the on_shutdown path @@ -8537,6 +8542,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(rctx, pg, pg->get_osdmap(), &handle); pg->unlock(); // kick source(s) to get them ready for (auto& i : children) { -- 2.39.5