|
@@ -3790,6 +3790,8 @@ int iscsi_target_tx_thread(void *arg)
|
|
|
{
|
|
|
int ret = 0;
|
|
|
struct iscsi_conn *conn = arg;
|
|
|
+ bool conn_freed = false;
|
|
|
+
|
|
|
/*
|
|
|
* Allow ourselves to be interrupted by SIGINT so that a
|
|
|
* connection recovery / failure event can be triggered externally.
|
|
@@ -3815,12 +3817,14 @@ get_immediate:
|
|
|
goto transport_err;
|
|
|
|
|
|
ret = iscsit_handle_response_queue(conn);
|
|
|
- if (ret == 1)
|
|
|
+ if (ret == 1) {
|
|
|
goto get_immediate;
|
|
|
- else if (ret == -ECONNRESET)
|
|
|
+ } else if (ret == -ECONNRESET) {
|
|
|
+ conn_freed = true;
|
|
|
goto out;
|
|
|
- else if (ret < 0)
|
|
|
+ } else if (ret < 0) {
|
|
|
goto transport_err;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
transport_err:
|
|
@@ -3830,8 +3834,13 @@ transport_err:
|
|
|
* responsible for cleaning up the early connection failure.
|
|
|
*/
|
|
|
if (conn->conn_state != TARG_CONN_STATE_IN_LOGIN)
|
|
|
- iscsit_take_action_for_connection_exit(conn);
|
|
|
+ iscsit_take_action_for_connection_exit(conn, &conn_freed);
|
|
|
out:
|
|
|
+ if (!conn_freed) {
|
|
|
+ while (!kthread_should_stop()) {
|
|
|
+ msleep(100);
|
|
|
+ }
|
|
|
+ }
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -4004,6 +4013,7 @@ int iscsi_target_rx_thread(void *arg)
|
|
|
{
|
|
|
int rc;
|
|
|
struct iscsi_conn *conn = arg;
|
|
|
+ bool conn_freed = false;
|
|
|
|
|
|
/*
|
|
|
* Allow ourselves to be interrupted by SIGINT so that a
|
|
@@ -4016,7 +4026,7 @@ int iscsi_target_rx_thread(void *arg)
|
|
|
*/
|
|
|
rc = wait_for_completion_interruptible(&conn->rx_login_comp);
|
|
|
if (rc < 0 || iscsi_target_check_conn_state(conn))
|
|
|
- return 0;
|
|
|
+ goto out;
|
|
|
|
|
|
if (!conn->conn_transport->iscsit_get_rx_pdu)
|
|
|
return 0;
|
|
@@ -4025,7 +4035,15 @@ int iscsi_target_rx_thread(void *arg)
|
|
|
|
|
|
if (!signal_pending(current))
|
|
|
atomic_set(&conn->transport_failed, 1);
|
|
|
- iscsit_take_action_for_connection_exit(conn);
|
|
|
+ iscsit_take_action_for_connection_exit(conn, &conn_freed);
|
|
|
+
|
|
|
+out:
|
|
|
+ if (!conn_freed) {
|
|
|
+ while (!kthread_should_stop()) {
|
|
|
+ msleep(100);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|