]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: signal mds sessions with Contexts instead of Conds
authorSage Weil <sage@inktank.com>
Mon, 22 Jul 2013 22:21:11 +0000 (15:21 -0700)
committerSage Weil <sage@inktank.com>
Tue, 23 Jul 2013 23:39:02 +0000 (16:39 -0700)
If we try to open an mds session and the MDS responds with close (aka,
"no"), we call _closed_mds_session() which signals the Cond*'s but then
deallocates the list.  wait_on_list() then does a use-after-free trying
to remove itself.

Instead, use Context*'s, so that the waiter does not reference the list.

Fixes: #5689
Signed-off-by: Sage Weil <sage@inktank.com>
Reviewed-by: Greg Farnum <greg@inktank.com>
src/client/Client.cc
src/client/MetaSession.h

index 7e7fa63c94f3c22ed6de4eb74ae748e662b21c24..ba036ad998036415cf94ae3b3a5d6dd6ec7ba649 100644 (file)
@@ -1303,7 +1303,7 @@ int Client::make_request(MetaRequest *request,
       // wait
       if (session->state == MetaSession::STATE_OPENING) {
        ldout(cct, 10) << "waiting for session to mds." << mds << " to open" << dendl;
-       wait_on_list(session->waiting_for_open);
+       wait_on_context_list(session->waiting_for_open);
        continue;
       }
 
@@ -1522,7 +1522,7 @@ void Client::_closed_mds_session(MetaSession *s)
 {
   s->state = MetaSession::STATE_CLOSED;
   messenger->mark_down(s->con);
-  signal_cond_list(s->waiting_for_open);
+  signal_context_list(s->waiting_for_open);
   mount_cond.Signal();
   remove_session_caps(s);
   kick_requests(s, true);
@@ -1549,7 +1549,7 @@ void Client::handle_client_session(MClientSession *m)
     if (!unmounting) {
       connect_mds_targets(from);
     }
-    signal_cond_list(session->waiting_for_open);
+    signal_context_list(session->waiting_for_open);
     break;
 
   case CEPH_SESSION_CLOSE:
@@ -1900,7 +1900,7 @@ void Client::handle_mds_map(MMDSMap* m)
       if (oldstate < MDSMap::STATE_ACTIVE) {
        kick_requests(p->second, false);
        kick_flushing_caps(p->second);
-       signal_cond_list(p->second->waiting_for_open);
+       signal_context_list(p->second->waiting_for_open);
        kick_maxsize_requests(p->second);
        wake_inode_waiters(p->second);
       }
@@ -7933,7 +7933,7 @@ void Client::ms_handle_remote_reset(Connection *con)
        case MetaSession::STATE_OPENING:
          {
            ldout(cct, 1) << "reset from mds we were opening; retrying" << dendl;
-           list<Cond*> waiters;
+           list<Context*> waiters;
            waiters.swap(s->waiting_for_open);
            _closed_mds_session(s);
            MetaSession *news = _get_or_open_mds_session(mds);
index 1f6a124061795b14470f551998ec9a5e15a77f27..01575efb6ba5f2e9de5d6e56510b72e8f70b6b36 100644 (file)
@@ -35,7 +35,7 @@ struct MetaSession {
     STATE_CLOSED,
   } state;
 
-  list<Cond*> waiting_for_open;
+  list<Context*> waiting_for_open;
 
   xlist<Cap*> caps;
   xlist<Inode*> flushing_caps;