diff options
author | Greg Farnum <greg@inktank.com> | 2013-09-19 09:54:56 -0700 |
---|---|---|
committer | Greg Farnum <greg@inktank.com> | 2013-09-23 09:57:45 -0700 |
commit | ac0748108e194ba15c5a167874c9932c92c3f30c (patch) | |
tree | 5fa608dbe1daa31d3dbad41d52534b2d6ce43b3a | |
parent | d0b5ae8b7097744bdccf1b0dff673274d03e8a1f (diff) | |
download | ceph-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.cc | 60 |
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; |