summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Farnum <greg@inktank.com>2013-09-19 09:54:56 -0700
committerGreg Farnum <greg@inktank.com>2013-09-23 09:57:45 -0700
commitac0748108e194ba15c5a167874c9932c92c3f30c (patch)
tree5fa608dbe1daa31d3dbad41d52534b2d6ce43b3a
parentd0b5ae8b7097744bdccf1b0dff673274d03e8a1f (diff)
downloadceph-ac0748108e194ba15c5a167874c9932c92c3f30c.tar.gz
ReplicatedPG: follow the same finish path for failed copy ops
We don't necessarily want to respond to clients with a failure if a copy got an error code. Instead, conditionally execute the success path and always launch back into execute_ctx() when the copy has stopped (either due to completion or failure). Update the COPY_FROM section so it returns the CopyOp::rval (instead of always zero) and only launches finish_copy() on success. Signed-off-by: Greg Farnum <greg@inktank.com>
-rw-r--r--src/osd/ReplicatedPG.cc60
1 files changed, 29 insertions, 31 deletions
diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc
index 1e3bfa17bbf..ffb0499fd44 100644
--- a/src/osd/ReplicatedPG.cc
+++ b/src/osd/ReplicatedPG.cc
@@ -3543,7 +3543,10 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
result = -EINPROGRESS;
} else {
// finish
- result = finish_copy(ctx);
+ result = ctx->copy_op->rval;
+ if (ctx->copy_op->rval >= 0) { // success!
+ result = finish_copy(ctx);
+ }
}
}
break;
@@ -4231,39 +4234,34 @@ void ReplicatedPG::process_copy_chunk(hobject_t oid, tid_t tid, int r)
}
OpContext *ctx = cop->ctx;
cop->objecter_tid = 0;
- if (r < 0) {
- copy_ops.erase(ctx->obc->obs.oi.soid);
- --ctx->obc->copyfrom_readside;
- kick_object_context_blocked(ctx->obc);
- reply_ctx(ctx, r);
- return;
- }
- assert(cop->rval >= 0);
-
- if (!cop->cursor.is_complete()) {
- // write out what we have so far
- vector<OSDOp> ops;
- tid_t rep_tid = osd->get_tid();
- osd_reqid_t reqid(osd->get_cluster_msgr_name(), 0, rep_tid);
- OpContext *tctx = new OpContext(OpRequestRef(), reqid, ops, &ctx->obc->obs, ctx->obc->ssc, this);
- tctx->mtime = ceph_clock_now(g_ceph_context);
- RepGather *repop = new_repop(tctx, ctx->obc, rep_tid);
-
- if (cop->temp_cursor.is_initial()) {
- cop->temp_coll = get_temp_coll(&tctx->local_t);
- cop->temp_oid = generate_temp_object();
- temp_contents.insert(cop->temp_oid);
- repop->ctx->new_temp_oid = cop->temp_oid;
- }
+ if (r >= 0) {
+ assert(cop->rval >= 0);
+
+ if (!cop->cursor.is_complete()) {
+ // write out what we have so far
+ vector<OSDOp> ops;
+ tid_t rep_tid = osd->get_tid();
+ osd_reqid_t reqid(osd->get_cluster_msgr_name(), 0, rep_tid);
+ OpContext *tctx = new OpContext(OpRequestRef(), reqid, ops, &ctx->obc->obs, ctx->obc->ssc, this);
+ tctx->mtime = ceph_clock_now(g_ceph_context);
+ RepGather *repop = new_repop(tctx, ctx->obc, rep_tid);
+
+ if (cop->temp_cursor.is_initial()) {
+ cop->temp_coll = get_temp_coll(&tctx->local_t);
+ cop->temp_oid = generate_temp_object();
+ temp_contents.insert(cop->temp_oid);
+ repop->ctx->new_temp_oid = cop->temp_oid;
+ }
- _write_copy_chunk(cop, &tctx->op_t);
+ _write_copy_chunk(cop, &tctx->op_t);
- issue_repop(repop, repop->ctx->mtime);
- eval_repop(repop);
+ issue_repop(repop, repop->ctx->mtime);
+ eval_repop(repop);
- dout(10) << __func__ << " fetching more" << dendl;
- _copy_some(ctx, cop);
- return;
+ dout(10) << __func__ << " fetching more" << dendl;
+ _copy_some(ctx, cop);
+ return;
+ }
}
dout(20) << __func__ << " complete; committing" << dendl;