diff options
author | Greg Farnum <greg@inktank.com> | 2013-10-10 09:58:57 -0700 |
---|---|---|
committer | Greg Farnum <greg@inktank.com> | 2013-10-17 13:11:45 -0700 |
commit | dc618492ea893ed513a811af7301faa5dbad345e (patch) | |
tree | a12706c39ec893b581bf1beeec27ab5de16549e9 | |
parent | b0e3dd179ec82b64c717a34c91063a036de0b913 (diff) | |
download | ceph-dc618492ea893ed513a811af7301faa5dbad345e.tar.gz |
ReplicatedPG: promote: handle failed promotes
If we get an error back, reply to the client directly and remove
the op which triggered promotion from our blocked op queue.
Signed-off-by: Greg Farnum <greg@inktank.com>
-rw-r--r-- | src/osd/ReplicatedPG.h | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/src/osd/ReplicatedPG.h b/src/osd/ReplicatedPG.h index 2448f86811d..6f5ea167550 100644 --- a/src/osd/ReplicatedPG.h +++ b/src/osd/ReplicatedPG.h @@ -219,11 +219,27 @@ public: virtual void finish(CopyCallbackResults results) { CopyResults* results_data = results.get<1>(); - assert(results.get<0>() == 0); // we don't handle errors right now - pg->finish_promote(results_data, obc, temp_obj); + int r = results.get<0>(); + if (r >= 0) { + pg->finish_promote(results_data, obc, temp_obj); + } else { + // we need to get rid of the op in the blocked queue + map<hobject_t,list<OpRequestRef> >::iterator blocked_iter; + blocked_iter = pg->waiting_for_blocked_object.find(obc->obs.oi.soid); + assert(blocked_iter != pg->waiting_for_blocked_object.end()); + assert(blocked_iter->second.begin()->get() == op.get()); + blocked_iter->second.pop_front(); + if (blocked_iter->second.empty()) { + pg->waiting_for_blocked_object.erase(blocked_iter); + } + if (r != -ECANCELED) { // on cancel the client will resend + pg->osd->reply_op_error(op, r); + } + } delete results_data; } }; + friend class PromoteCallback; boost::scoped_ptr<PGBackend> pgbackend; PGBackend *get_pgbackend() { |