Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7bb21d68 authored by Alex Elder's avatar Alex Elder
Browse files

libceph: socket can close in any connection state



A connection's socket can close for any reason, independent of the
state of the connection (and without irrespective of the connection
mutex).  As a result, the connectino can be in pretty much any state
at the time its socket is closed.

Handle those other cases at the top of con_work().  Pull this whole
block of code into a separate function to reduce the clutter.

Signed-off-by: default avatarAlex Elder <elder@inktank.com>
Reviewed-by: default avatarSage Weil <sage@inktank.com>
parent b8f5c6ed
Loading
Loading
Loading
Loading
+30 −17
Original line number Diff line number Diff line
@@ -2273,6 +2273,35 @@ static void queue_con(struct ceph_connection *con)
	(void) queue_con_delay(con, 0);
}

static bool con_sock_closed(struct ceph_connection *con)
{
	if (!test_and_clear_bit(CON_FLAG_SOCK_CLOSED, &con->flags))
		return false;

#define CASE(x)								\
	case CON_STATE_ ## x:						\
		con->error_msg = "socket closed (con state " #x ")";	\
		break;

	switch (con->state) {
	CASE(CLOSED);
	CASE(PREOPEN);
	CASE(CONNECTING);
	CASE(NEGOTIATING);
	CASE(OPEN);
	CASE(STANDBY);
	default:
		pr_warning("%s con %p unrecognized state %lu\n",
			__func__, con, con->state);
		con->error_msg = "unrecognized con state";
		BUG();
		break;
	}
#undef CASE

	return true;
}

/*
 * Do some work on a connection.  Drop a connection ref when we're done.
 */
@@ -2284,24 +2313,8 @@ static void con_work(struct work_struct *work)

	mutex_lock(&con->mutex);
restart:
	if (test_and_clear_bit(CON_FLAG_SOCK_CLOSED, &con->flags)) {
		switch (con->state) {
		case CON_STATE_CONNECTING:
			con->error_msg = "connection failed";
			break;
		case CON_STATE_NEGOTIATING:
			con->error_msg = "negotiation failed";
			break;
		case CON_STATE_OPEN:
			con->error_msg = "socket closed";
			break;
		default:
			dout("unrecognized con state %d\n", (int)con->state);
			con->error_msg = "unrecognized con state";
			BUG();
		}
	if (con_sock_closed(con))
		goto fault;
	}

	if (test_and_clear_bit(CON_FLAG_BACKOFF, &con->flags)) {
		dout("con_work %p backing off\n", con);