]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: dispatch_context and queue split finish on early bail-out 32942/head
authorSage Weil <sage@redhat.com>
Tue, 28 Jan 2020 19:33:49 +0000 (13:33 -0600)
committerSage Weil <sage@redhat.com>
Tue, 28 Jan 2020 19:33:53 +0000 (13:33 -0600)
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 <sage@redhat.com>
src/osd/OSD.cc

index c7eab55878968c7e6632878568ae1def690024af..6d7119008742597a3368155948dcb81527a81b77 100644 (file)
@@ -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) {