From: Sage Weil Date: Mon, 22 Jul 2013 22:21:11 +0000 (-0700) Subject: client: signal mds sessions with Contexts instead of Conds X-Git-Tag: v0.67-rc2~12 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=2338a329f5771918a3617101d518f56e1514079a;p=ceph.git client: signal mds sessions with Contexts instead of Conds 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 Reviewed-by: Greg Farnum --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 7e7fa63c94f3..ba036ad99803 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -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 waiters; + list waiters; waiters.swap(s->waiting_for_open); _closed_mds_session(s); MetaSession *news = _get_or_open_mds_session(mds); diff --git a/src/client/MetaSession.h b/src/client/MetaSession.h index 1f6a12406179..01575efb6ba5 100644 --- a/src/client/MetaSession.h +++ b/src/client/MetaSession.h @@ -35,7 +35,7 @@ struct MetaSession { STATE_CLOSED, } state; - list waiting_for_open; + list waiting_for_open; xlist caps; xlist flushing_caps;