forked from Minki/linux
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: Alex Elder <elder@inktank.com> Reviewed-by: Sage Weil <sage@inktank.com>
This commit is contained in:
parent
b8f5c6edca
commit
7bb21d68c5
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user