From: Sage Weil Date: Thu, 17 Apr 2014 20:11:54 +0000 (-0700) Subject: osd/ReplicatedPG: check clones for degraded X-Git-Tag: v0.80-rc1~26^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F1688%2Fhead;p=ceph.git 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 --- diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 723b5e0605da..1a5d28128b90 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) {