]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: Fix problems in ReplicatedPG::do_op() logic
authorDavid Zafman <david.zafman@inktank.com>
Wed, 11 Dec 2013 01:29:48 +0000 (17:29 -0800)
committerSamuel Just <sam.just@inktank.com>
Wed, 8 Oct 2014 22:55:21 +0000 (15:55 -0700)
Fix assert(is_degraded_object(soid)) in ReplicatedPG::wait_for_degraded_object()
  Use last_backfill_started as the backfill line
  Handle uncommon case of multi op source after backfill line and target before
  backfill line and !is_degraded_object().
  Include backfill line itself for before_backfill (<= instead of <)

Signed-off-by: David Zafman <david.zafman@inktank.com>
(cherry picked from commit 7837490a9d5fc467a2cc25400f94979d8d4b4d8e)

src/osd/ReplicatedPG.cc

index 614ef4eb8be933f4913d2b04dab180b5b5646813..75fbd75b74daca517c8b584e61da76177f421bb9 100644 (file)
@@ -800,11 +800,13 @@ void ReplicatedPG::do_op(OpRequestRef op)
   // operation won't apply properly on the backfill_target.  (the
   // opposite is not a problem; if the target is after the line, we
   // don't apply on the backfill_target and it doesn't matter.)
+  // The last_backfill_started is used as the backfill line since
+  // that determines the boundary for writes.
   pg_info_t *backfill_target_info = NULL;
   bool before_backfill = false;
   if (backfill_target >= 0) {
     backfill_target_info = &peer_info[backfill_target];
-    before_backfill = obc->obs.oi.soid < backfill_target_info->last_backfill;
+    before_backfill = obc->obs.oi.soid <= last_backfill_started;
   }
 
   // src_oids
@@ -848,8 +850,13 @@ void ReplicatedPG::do_op(OpRequestRef op)
                  << obc->obs.oi.soid << dendl;
            osd->reply_op_error(op, -EINVAL);
          } else if (is_degraded_object(sobc->obs.oi.soid) ||
-                  (before_backfill && sobc->obs.oi.soid > backfill_target_info->last_backfill)) {
-           wait_for_degraded_object(sobc->obs.oi.soid, op);
+                  (before_backfill && sobc->obs.oi.soid > last_backfill_started)) {
+           if (is_degraded_object(sobc->obs.oi.soid)) {
+             wait_for_degraded_object(sobc->obs.oi.soid, op);
+           } else {
+             waiting_for_degraded_object[sobc->obs.oi.soid].push_back(op);
+             op->mark_delayed("waiting for degraded object");
+           }
            dout(10) << " writes for " << obc->obs.oi.soid << " now blocked by "
                   << sobc->obs.oi.soid << dendl;
            obc->get();