Commit 3596f4c1 authored by Ilya Dryomov's avatar Ilya Dryomov
Browse files

libceph: split protocol reset bits out of reset_connection()



Move protocol reset bits into ceph_con_reset_protocol(), leaving
just session reset bits.

Note that con->out_skip is now reset on faults.  This fixes a crash
in the case of a stateful session getting a fault while in the middle
of revoking a message.

Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 90b6561a
Loading
Loading
Loading
Loading
+24 −26
Original line number Diff line number Diff line
@@ -613,6 +613,25 @@ static int con_close_socket(struct ceph_connection *con)
	return rc;
}

static void ceph_con_reset_protocol(struct ceph_connection *con)
{
	dout("%s con %p\n", __func__, con);

	con_close_socket(con);
	if (con->in_msg) {
		WARN_ON(con->in_msg->con != con);
		ceph_msg_put(con->in_msg);
		con->in_msg = NULL;
	}
	if (con->out_msg) {
		WARN_ON(con->out_msg->con != con);
		ceph_msg_put(con->out_msg);
		con->out_msg = NULL;
	}

	con->out_skip = 0;
}

/*
 * Reset a connection.  Discard all incoming and outgoing messages
 * and clear *_seq state.
@@ -637,26 +656,16 @@ static void reset_connection(struct ceph_connection *con)
	/* reset connection, out_queue, msg_ and connect_seq */
	/* discard existing out_queue and msg_seq */
	dout("reset_connection %p\n", con);

	WARN_ON(con->in_msg);
	WARN_ON(con->out_msg);
	ceph_msg_remove_list(&con->out_queue);
	ceph_msg_remove_list(&con->out_sent);

	if (con->in_msg) {
		BUG_ON(con->in_msg->con != con);
		ceph_msg_put(con->in_msg);
		con->in_msg = NULL;
	}

	con->connect_seq = 0;
	con->out_seq = 0;
	if (con->out_msg) {
		BUG_ON(con->out_msg->con != con);
		ceph_msg_put(con->out_msg);
		con->out_msg = NULL;
	}
	con->in_seq = 0;
	con->in_seq_acked = 0;

	con->out_skip = 0;
}

/*
@@ -673,10 +682,10 @@ void ceph_con_close(struct ceph_connection *con)
	con_flag_clear(con, CON_FLAG_WRITE_PENDING);
	con_flag_clear(con, CON_FLAG_BACKOFF);

	ceph_con_reset_protocol(con);
	reset_connection(con);
	con->peer_global_seq = 0;
	cancel_con(con);
	con_close_socket(con);
	mutex_unlock(&con->mutex);
}
EXPORT_SYMBOL(ceph_con_close);
@@ -2986,7 +2995,7 @@ static void con_fault(struct ceph_connection *con)
	       con->state != CON_STATE_NEGOTIATING &&
	       con->state != CON_STATE_OPEN);

	con_close_socket(con);
	ceph_con_reset_protocol(con);

	if (con_flag_test(con, CON_FLAG_LOSSYTX)) {
		dout("fault on LOSSYTX channel, marking CLOSED\n");
@@ -2994,17 +3003,6 @@ static void con_fault(struct ceph_connection *con)
		return;
	}

	if (con->in_msg) {
		BUG_ON(con->in_msg->con != con);
		ceph_msg_put(con->in_msg);
		con->in_msg = NULL;
	}
	if (con->out_msg) {
		BUG_ON(con->out_msg->con != con);
		ceph_msg_put(con->out_msg);
		con->out_msg = NULL;
	}

	/* Requeue anything that hasn't been acked */
	list_splice_init(&con->out_sent, &con->out_queue);