From bddbda121c8d52ba8e50abd0341f14e332c6af5a Mon Sep 17 00:00:00 2001 From: xiexingguo <258156334@qq.com> Date: Thu, 29 Oct 2015 20:04:11 +0800 Subject: [PATCH] Objecter: pool_op callback may hang forever. pool_op callback may hang forever due to osdmap update during reply handling. Fixes: #13642 Signed-off-by: xie xingguo (cherry picked from commit 00c6fa9e31975a935ed2bb33a099e2b4f02ad7f2) --- src/osdc/Objecter.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc index 9f35ffdda753c..faddcd4fc1db3 100644 --- a/src/osdc/Objecter.cc +++ b/src/osdc/Objecter.cc @@ -3626,12 +3626,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; @@ -3646,6 +3658,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; -- 2.39.5