]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: set the blocked_by relationship when rolling back to a degraded
authorZhiqiang Wang <zhiqiang.wang@intel.com>
Tue, 2 Jun 2015 08:20:35 +0000 (16:20 +0800)
committerSamuel Just <sjust@redhat.com>
Tue, 18 Aug 2015 18:25:23 +0000 (11:25 -0700)
object

In a scenario like below:
- A rollback op comes in, and is enqueued.
- Several other ops on the same object come in, and are enqueued.
- The rollback op dispatches, and finds the object which it rollbacks to is
degraded, then this op is pushbacked into a list to wait for the degraded
object to recover.
- The later ops are handled and responded back to client.
- The degraded object recovers. The rollback op is enqueued again and finally
responded to client.
This breaks the op order. Need to set the blocked_by relationship to enqueue
the later ops until the degraded object recovers.

Signed-off-by: Zhiqiang Wang <zhiqiang.wang@intel.com>
src/osd/ReplicatedPG.cc

index aa87d85a9886e0d044fba33a2ad4e72294e9e1a2..96f0994eb8522a2734f74098c49db5e9ecd48fa9 100644 (file)
@@ -5493,6 +5493,8 @@ int ReplicatedPG::_rollback_to(OpContext *ctx, ceph_osd_op& op)
     if (is_degraded_or_backfilling_object(rollback_to_sobject)) {
       dout(20) << "_rollback_to attempted to roll back to a degraded object "
               << rollback_to_sobject << " (requested snapid: ) " << snapid << dendl;
+      ctx->obc->blocked_by = rollback_to;
+      rollback_to->blocking.insert(ctx->obc);
       wait_for_degraded_object(rollback_to_sobject, ctx->op);
       ret = -EAGAIN;
     } else if (rollback_to->obs.oi.soid.snap == CEPH_NOSNAP) {