]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix null pointer dereference in Locker::handle_client_caps 13060/head
authorYan, Zheng <zyan@redhat.com>
Fri, 6 Jan 2017 07:42:52 +0000 (15:42 +0800)
committerAlexey Sheplyakov <asheplyakov@mirantis.com>
Mon, 23 Jan 2017 08:05:47 +0000 (12:05 +0400)
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 <zyan@redhat.com>
(cherry picked from commit e281a0b9c1fdeaf09f1b01f34cecd62e4f49d02e)

src/mds/Locker.cc

index 10fff9848c997013c4099b7ffe98af939854646c..70b4a34d629af63dc8a86ed5fa1cf132d01e8acf 100644 (file)
@@ -2467,6 +2467,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())) {
@@ -2476,7 +2488,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;
@@ -2503,7 +2515,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);