From 734e9af5df4ae419ded108f5036bee068a9bc2b2 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 1 Dec 2014 18:15:59 -0800 Subject: [PATCH] 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 (cherry picked from commit 01df2227125abf94571b4b0c7bccca57098ed2dc) --- src/osd/OSD.cc | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 4c8b4da8c1f4a..ff132c65ddc2e 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -2773,7 +2773,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()); @@ -5504,14 +5505,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); } @@ -5521,10 +5523,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(); + } } } } @@ -5729,13 +5733,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; } @@ -8186,7 +8192,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); -- 2.39.5