Commit 6f0f597b authored by Yan, Zheng's avatar Yan, Zheng Committed by Ilya Dryomov
Browse files

ceph: don't blindly unregister session that is in opening state

handle_cap_export() may add placeholder caps to session that is in
opening state. These caps' session pointer become wild after session get
unregistered.

The fix is not to unregister session in opening state during mds failovers,
just let client to reconnect later when mds is recovered.

Link: https://tracker.ceph.com/issues/40190


Signed-off-by: default avatar"Yan, Zheng" <zyan@redhat.com>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 2ef5df1a
Loading
Loading
Loading
Loading
+26 −33
Original line number Diff line number Diff line
@@ -3737,23 +3737,11 @@ static void check_new_map(struct ceph_mds_client *mdsc,
		     ceph_mdsmap_is_laggy(newmap, i) ? " (laggy)" : "",
		     ceph_session_state_name(s->s_state));

		if (i >= newmap->m_num_mds ||
		    memcmp(ceph_mdsmap_get_addr(oldmap, i),
			   ceph_mdsmap_get_addr(newmap, i),
			   sizeof(struct ceph_entity_addr))) {
			if (s->s_state == CEPH_MDS_SESSION_OPENING) {
				/* the session never opened, just close it
				 * out now */
				get_session(s);
				__unregister_session(mdsc, s);
				__wake_requests(mdsc, &s->s_waiting);
				ceph_put_mds_session(s);
			} else if (i >= newmap->m_num_mds) {
		if (i >= newmap->m_num_mds) {
			/* force close session for stopped mds */
			get_session(s);
			__unregister_session(mdsc, s);
			__wake_requests(mdsc, &s->s_waiting);
				kick_requests(mdsc, i);
			mutex_unlock(&mdsc->mutex);

			mutex_lock(&s->s_mutex);
@@ -3764,7 +3752,13 @@ static void check_new_map(struct ceph_mds_client *mdsc,
			ceph_put_mds_session(s);

			mutex_lock(&mdsc->mutex);
			} else {
			kick_requests(mdsc, i);
			continue;
		}

		if (memcmp(ceph_mdsmap_get_addr(oldmap, i),
			   ceph_mdsmap_get_addr(newmap, i),
			   sizeof(struct ceph_entity_addr))) {
			/* just close it */
			mutex_unlock(&mdsc->mutex);
			mutex_lock(&s->s_mutex);
@@ -3772,7 +3766,6 @@ static void check_new_map(struct ceph_mds_client *mdsc,
			ceph_con_close(&s->s_con);
			mutex_unlock(&s->s_mutex);
			s->s_state = CEPH_MDS_SESSION_RESTARTING;
			}
		} else if (oldstate == newstate) {
			continue;  /* nothing new with this mds */
		}