summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Farnum <greg@inktank.com>2013-10-10 09:58:57 -0700
committerGreg Farnum <greg@inktank.com>2013-10-10 09:58:57 -0700
commitb5bab6590ea2a66ad74d249a0bc0970717772b0e (patch)
treed875fecad967c4728fda5dafae433d16699bc23a
parent5be7db92ee984ba96226ced2f953f78187a5f97b (diff)
downloadceph-b5bab6590ea2a66ad74d249a0bc0970717772b0e.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.h20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/osd/ReplicatedPG.h b/src/osd/ReplicatedPG.h
index e57df429279..1435490c657 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() {