From: Yan, Zheng Date: Fri, 6 Jan 2017 07:42:52 +0000 (+0800) Subject: mds: fix null pointer dereference in Locker::handle_client_caps X-Git-Tag: v11.2.1~141^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F14566%2Fhead;p=ceph.git mds: fix null pointer dereference in Locker::handle_client_caps Locker::handle_client_caps delays processing cap message if the corresponding inode is freezing or frozen. When the message gets processed, client can have already closed the session. Fixes: http://tracker.ceph.com/issues/18306 Signed-off-by: Yan, Zheng (cherry picked from commit e281a0b9c1fdeaf09f1b01f34cecd62e4f49d02e) --- diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index f576a1a539e08..accf99843b5a7 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -2495,6 +2495,18 @@ void Locker::handle_client_caps(MClientCaps *m) << " op " << ceph_cap_op_name(m->get_op()) << dendl; if (!mds->is_clientreplay() && !mds->is_active() && !mds->is_stopping()) { + if (!session) { + dout(5) << " no session, dropping " << *m << dendl; + m->put(); + return; + } + if (session->is_closed() || + session->is_closing() || + session->is_killing()) { + dout(7) << " session closed|closing|killing, dropping " << *m << dendl; + m->put(); + return; + } if (mds->is_reconnect() && m->get_dirty() && m->get_client_tid() > 0 && !session->have_completed_flush(m->get_client_tid())) { @@ -2504,7 +2516,7 @@ void Locker::handle_client_caps(MClientCaps *m) return; } - if (m->get_client_tid() > 0 && + if (m->get_client_tid() > 0 && session && session->have_completed_flush(m->get_client_tid())) { dout(7) << "handle_client_caps already flushed tid " << m->get_client_tid() << " for client." << client << dendl; @@ -2531,7 +2543,7 @@ void Locker::handle_client_caps(MClientCaps *m) } // "oldest flush tid" > 0 means client uses unique TID for each flush - if (m->get_oldest_flush_tid() > 0) { + if (m->get_oldest_flush_tid() > 0 && session) { if (session->trim_completed_flushes(m->get_oldest_flush_tid())) { mds->mdlog->get_current_segment()->touched_sessions.insert(session->info.inst.name);