]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/ReplicatedPG: check clones for degraded 1688/head
authorSage Weil <sage@inktank.com>
Thu, 17 Apr 2014 20:11:54 +0000 (13:11 -0700)
committerSage Weil <sage@inktank.com>
Thu, 17 Apr 2014 20:11:54 +0000 (13:11 -0700)
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 <sage@inktank.com>
src/osd/ReplicatedPG.cc

index 723b5e0605da800c1187aaa56b5cdb57f7c5eead..1a5d28128b90838c763087bbfd5d865965371dcb 100644 (file)
@@ -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) {