From 110c35498942ea0feec395b6e7992f802dd740ce Mon Sep 17 00:00:00 2001 From: Samuel Just Date: Fri, 20 Mar 2015 15:28:15 -0700 Subject: [PATCH] ReplicatedPG::promote_object: check scrubber and block if necessary Otherwise, we might attempt to promote into an in-progress scrub interval causing 11156. I would have added a return value to promote_object(), but could not find an existing user which cared to distinguish the cases, even with a null op passed. All existing users are in maybe_handle_cache. The ones which pass a null op are for promoting the object in parallel with a proxy -- a case where not actually performing the promote does not really matter. Fixes: #11156 Signed-off-by: Samuel Just (cherry picked from commit 65bb4df599541cd2e0f195b905f24f529e255c00) --- src/osd/ReplicatedPG.cc | 13 +++++++++++++ src/osd/ReplicatedPG.h | 5 ++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 25b026961cfed..ed7abb5427538 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -1697,6 +1697,19 @@ void ReplicatedPG::promote_object(OpRequestRef op, ObjectContextRef obc, obc = get_object_context(missing_oid, true); } dout(10) << __func__ << " " << obc->obs.oi.soid << dendl; + if (scrubber.write_blocked_by_scrub(obc->obs.oi.soid)) { + dout(10) << __func__ << " " << obc->obs.oi.soid + << " blocked by scrub" << dendl; + if (op) { + waiting_for_active.push_back(op); + dout(10) << __func__ << " " << obc->obs.oi.soid + << " placing op in waiting_for_active" << dendl; + } else { + dout(10) << __func__ << " " << obc->obs.oi.soid + << " no op, dropping on the floor" << dendl; + } + return; + } PromoteCallback *cb = new PromoteCallback(op, obc, this); object_locator_t oloc(m->get_object_locator()); diff --git a/src/osd/ReplicatedPG.h b/src/osd/ReplicatedPG.h index dc8ee62585949..4b0d1d6944187 100644 --- a/src/osd/ReplicatedPG.h +++ b/src/osd/ReplicatedPG.h @@ -1060,7 +1060,10 @@ protected: */ void do_cache_redirect(OpRequestRef op, ObjectContextRef obc); /** - * This function starts up a copy from + * This function attempts to start a promote. Either it succeeds, + * or places op on a wait list. If op is null, failure means that + * this is a noop. If a future user wants to be able to distinguish + * these cases, a return value should be added. */ void promote_object(OpRequestRef op, ObjectContextRef obc, const hobject_t& missing_object); -- 2.39.5