]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Objecter: pool_op callback may hang forever. 6627/head
authorxiexingguo <258156334@qq.com>
Thu, 29 Oct 2015 12:04:11 +0000 (20:04 +0800)
committerAbhishek Varshney <abhishek.varshney@flipkart.com>
Wed, 18 Nov 2015 07:20:29 +0000 (12:50 +0530)
pool_op callback may hang forever due to osdmap update during reply handling.
Fixes: #13642
Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
(cherry picked from commit 00c6fa9e31975a935ed2bb33a099e2b4f02ad7f2)

src/osdc/Objecter.cc

index 60efe3ae469d5eafcdb024b7b822c34bf3e72ed1..53cd2ddeade5ff041e66651ed7047ee022334535 100644 (file)
@@ -3764,12 +3764,24 @@ void Objecter::handle_pool_op_reply(MPoolOpReply *m)
     if (osdmap->get_epoch() < m->epoch) {
       rwlock.unlock();
       rwlock.get_write();
+      // recheck op existence since we have let go of rwlock
+      // (for promotion) above.
+      iter = pool_ops.find(tid);
+      if (iter == pool_ops.end())
+        goto done; // op is gone.
       if (osdmap->get_epoch() < m->epoch) {
         ldout(cct, 20) << "waiting for client to reach epoch " << m->epoch << " before calling back" << dendl;
         _wait_for_new_map(op->onfinish, m->epoch, m->replyCode);
+      } else {
+       // map epoch changed, probably because a MOSDMap message
+       // sneaked in. Do caller-specified callback now or else
+       // we lose it forever.
+       assert(op->onfinish);
+       op->onfinish->complete(m->replyCode);   
       }
     }
     else {
+      assert(op->onfinish);
       op->onfinish->complete(m->replyCode);
     }
     op->onfinish = NULL;
@@ -3784,6 +3796,8 @@ void Objecter::handle_pool_op_reply(MPoolOpReply *m)
   } else {
     ldout(cct, 10) << "unknown request " << tid << dendl;
   }
+
+done:
   rwlock.unlock();
 
   ldout(cct, 10) << "done" << dendl;