]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ReplicatedPG: promote: handle failed promotes
authorGreg Farnum <greg@inktank.com>
Thu, 10 Oct 2013 16:58:57 +0000 (09:58 -0700)
committerSage Weil <sage@inktank.com>
Sat, 14 Dec 2013 00:35:52 +0000 (16:35 -0800)
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>
Reviewed-by: Sage Weil <sage@inktank.com>
src/osd/ReplicatedPG.h

index 5e8aa21e1a1315a7f7ddb3ea415285c4126baa2f..43c61b72e41762ea186322a889862e4235d97c87 100644 (file)
@@ -223,11 +223,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() {