]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix null pointer dereference in Locker::handle_client_caps 14566/head
authorYan, Zheng <zyan@redhat.com>
Fri, 6 Jan 2017 07:42:52 +0000 (15:42 +0800)
committerNathan Cutler <ncutler@suse.com>
Fri, 14 Apr 2017 21:44:44 +0000 (23:44 +0200)
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 f576a1a539e0886041cb139abccb2acf2ffa3495..accf99843b5a78689b16167b73b8823173d71451 100644 (file)
@@ -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);