From 3d0e80acd9e3e1c751c871742313173f14abbea6 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 17 Apr 2014 13:11:54 -0700 Subject: [PATCH] osd/ReplicatedPG: check clones for degraded We check whether the head is degraded, and we check whether a clone is unreadable, but in the case where we have a cache op on a degraded object, we don't check. That leads to an assert when the repop hits the replica and the object is in the peer's missing set. Fix this by adding a check on the clone when write_ordered is true. Note that checking write_ordered is better than whether it is a cache op because we want to preserve write ordering even for reads that are flagged by the client. Fixes: #8048 Signed-off-by: Sage Weil --- src/osd/ReplicatedPG.cc | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 723b5e0605da8..1a5d28128b908 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -1276,11 +1276,23 @@ void ReplicatedPG::do_op(OpRequestRef op) wait_for_unreadable_object(missing_oid, op); return; } - } else if (r == 0 && is_unreadable_object(obc->obs.oi.soid)) { - dout(10) << __func__ << ": clone " << obc->obs.oi.soid - << " is unreadable, waiting" << dendl; - wait_for_unreadable_object(obc->obs.oi.soid, op); - return; + } else if (r == 0) { + if (is_unreadable_object(obc->obs.oi.soid)) { + dout(10) << __func__ << ": clone " << obc->obs.oi.soid + << " is unreadable, waiting" << dendl; + wait_for_unreadable_object(obc->obs.oi.soid, op); + return; + } + + // degraded object? (the check above was for head; this could be a clone) + if (write_ordered && + obc->obs.oi.soid.snap != CEPH_NOSNAP && + is_degraded_object(obc->obs.oi.soid)) { + dout(10) << __func__ << ": clone " << obc->obs.oi.soid + << " is degraded, waiting" << dendl; + wait_for_degraded_object(obc->obs.oi.soid, op); + return; + } } if (hit_set) { -- 2.39.5