|
@@ -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);
|