From: Sage Weil Date: Tue, 2 Dec 2014 02:15:59 +0000 (-0800) Subject: osd: tolerate sessionless con in fast dispatch path X-Git-Tag: v0.91~165^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F3048%2Fhead;p=ceph.git osd: tolerate sessionless con in fast dispatch path We can now get a session cleared from a Connection at any time. Change the assert to an if in ms_fast_dispatch to cope. It's pretty rare, but it can happen, especially with delay injection. In particular, a racing thread can call mark_down() on us. Fixes: #10209 Backport: giant Signed-off-by: Sage Weil --- diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 283a5178c5e..f1c28457cb6 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -2648,7 +2648,8 @@ PG *OSD::get_pg_or_queue_for_pg(const spg_t& pgid, OpRequestRef& op) { Session *session = static_cast( op->get_req()->get_connection()->get_priv()); - assert(session); + if (!session) + return NULL; // get_pg_or_queue_for_pg is only called from the fast_dispatch path where // the session_dispatch_lock must already be held. assert(session->session_dispatch_lock.is_locked()); @@ -5407,14 +5408,15 @@ void OSD::ms_fast_dispatch(Message *m) } OSDMapRef nextmap = service.get_nextmap_reserved(); Session *session = static_cast(m->get_connection()->get_priv()); - assert(session); - { - Mutex::Locker l(session->session_dispatch_lock); - update_waiting_for_pg(session, nextmap); - session->waiting_on_map.push_back(op); - dispatch_session_waiting(session, nextmap); + if (session) { + { + Mutex::Locker l(session->session_dispatch_lock); + update_waiting_for_pg(session, nextmap); + session->waiting_on_map.push_back(op); + dispatch_session_waiting(session, nextmap); + } + session->put(); } - session->put(); service.release_map(nextmap); } @@ -5424,10 +5426,12 @@ void OSD::ms_fast_preprocess(Message *m) if (m->get_type() == CEPH_MSG_OSD_MAP) { MOSDMap *mm = static_cast(m); Session *s = static_cast(m->get_connection()->get_priv()); - s->received_map_lock.Lock(); - s->received_map_epoch = mm->get_last(); - s->received_map_lock.Unlock(); - s->put(); + if (s) { + s->received_map_lock.Lock(); + s->received_map_epoch = mm->get_last(); + s->received_map_lock.Unlock(); + s->put(); + } } } } @@ -5632,13 +5636,15 @@ bool OSD::dispatch_op_fast(OpRequestRef& op, OSDMapRef& osdmap) if (msg_epoch > osdmap->get_epoch()) { Session *s = static_cast(op->get_req()-> get_connection()->get_priv()); - s->received_map_lock.Lock(); - epoch_t received_epoch = s->received_map_epoch; - s->received_map_lock.Unlock(); - if (received_epoch < msg_epoch) { - osdmap_subscribe(msg_epoch, false); + if (s) { + s->received_map_lock.Lock(); + epoch_t received_epoch = s->received_map_epoch; + s->received_map_lock.Unlock(); + if (received_epoch < msg_epoch) { + osdmap_subscribe(msg_epoch, false); + } + s->put(); } - s->put(); return false; } @@ -8098,7 +8104,7 @@ void OSD::handle_replica_op(OpRequestRef& op, OSDMapRef& osdmap) op->send_map_update = should_share_map; op->sent_epoch = m->map_epoch; enqueue_op(pg, op); - } else if (should_share_map) { + } else if (should_share_map && m->get_connection()->is_connected()) { C_SendMap *send_map = new C_SendMap(this, m->get_source(), m->get_connection(), osdmap, m->map_epoch);