diff options
| -rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 30 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_erl0.c | 6 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_erl0.h | 2 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_login.c | 4 |
4 files changed, 34 insertions, 8 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 26a9bcd5ee6a..0d8f81591bed 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
| @@ -3790,6 +3790,8 @@ int iscsi_target_tx_thread(void *arg) | |||
| 3790 | { | 3790 | { |
| 3791 | int ret = 0; | 3791 | int ret = 0; |
| 3792 | struct iscsi_conn *conn = arg; | 3792 | struct iscsi_conn *conn = arg; |
| 3793 | bool conn_freed = false; | ||
| 3794 | |||
| 3793 | /* | 3795 | /* |
| 3794 | * Allow ourselves to be interrupted by SIGINT so that a | 3796 | * Allow ourselves to be interrupted by SIGINT so that a |
| 3795 | * connection recovery / failure event can be triggered externally. | 3797 | * connection recovery / failure event can be triggered externally. |
| @@ -3815,12 +3817,14 @@ get_immediate: | |||
| 3815 | goto transport_err; | 3817 | goto transport_err; |
| 3816 | 3818 | ||
| 3817 | ret = iscsit_handle_response_queue(conn); | 3819 | ret = iscsit_handle_response_queue(conn); |
| 3818 | if (ret == 1) | 3820 | if (ret == 1) { |
| 3819 | goto get_immediate; | 3821 | goto get_immediate; |
| 3820 | else if (ret == -ECONNRESET) | 3822 | } else if (ret == -ECONNRESET) { |
| 3823 | conn_freed = true; | ||
| 3821 | goto out; | 3824 | goto out; |
| 3822 | else if (ret < 0) | 3825 | } else if (ret < 0) { |
| 3823 | goto transport_err; | 3826 | goto transport_err; |
| 3827 | } | ||
| 3824 | } | 3828 | } |
| 3825 | 3829 | ||
| 3826 | transport_err: | 3830 | transport_err: |
| @@ -3830,8 +3834,13 @@ transport_err: | |||
| 3830 | * responsible for cleaning up the early connection failure. | 3834 | * responsible for cleaning up the early connection failure. |
| 3831 | */ | 3835 | */ |
| 3832 | if (conn->conn_state != TARG_CONN_STATE_IN_LOGIN) | 3836 | if (conn->conn_state != TARG_CONN_STATE_IN_LOGIN) |
| 3833 | iscsit_take_action_for_connection_exit(conn); | 3837 | iscsit_take_action_for_connection_exit(conn, &conn_freed); |
| 3834 | out: | 3838 | out: |
| 3839 | if (!conn_freed) { | ||
| 3840 | while (!kthread_should_stop()) { | ||
| 3841 | msleep(100); | ||
| 3842 | } | ||
| 3843 | } | ||
| 3835 | return 0; | 3844 | return 0; |
| 3836 | } | 3845 | } |
| 3837 | 3846 | ||
| @@ -4004,6 +4013,7 @@ int iscsi_target_rx_thread(void *arg) | |||
| 4004 | { | 4013 | { |
| 4005 | int rc; | 4014 | int rc; |
| 4006 | struct iscsi_conn *conn = arg; | 4015 | struct iscsi_conn *conn = arg; |
| 4016 | bool conn_freed = false; | ||
| 4007 | 4017 | ||
| 4008 | /* | 4018 | /* |
| 4009 | * Allow ourselves to be interrupted by SIGINT so that a | 4019 | * Allow ourselves to be interrupted by SIGINT so that a |
| @@ -4016,7 +4026,7 @@ int iscsi_target_rx_thread(void *arg) | |||
| 4016 | */ | 4026 | */ |
| 4017 | rc = wait_for_completion_interruptible(&conn->rx_login_comp); | 4027 | rc = wait_for_completion_interruptible(&conn->rx_login_comp); |
| 4018 | if (rc < 0 || iscsi_target_check_conn_state(conn)) | 4028 | if (rc < 0 || iscsi_target_check_conn_state(conn)) |
| 4019 | return 0; | 4029 | goto out; |
| 4020 | 4030 | ||
| 4021 | if (!conn->conn_transport->iscsit_get_rx_pdu) | 4031 | if (!conn->conn_transport->iscsit_get_rx_pdu) |
| 4022 | return 0; | 4032 | return 0; |
| @@ -4025,7 +4035,15 @@ int iscsi_target_rx_thread(void *arg) | |||
| 4025 | 4035 | ||
| 4026 | if (!signal_pending(current)) | 4036 | if (!signal_pending(current)) |
| 4027 | atomic_set(&conn->transport_failed, 1); | 4037 | atomic_set(&conn->transport_failed, 1); |
| 4028 | iscsit_take_action_for_connection_exit(conn); | 4038 | iscsit_take_action_for_connection_exit(conn, &conn_freed); |
| 4039 | |||
| 4040 | out: | ||
| 4041 | if (!conn_freed) { | ||
| 4042 | while (!kthread_should_stop()) { | ||
| 4043 | msleep(100); | ||
| 4044 | } | ||
| 4045 | } | ||
| 4046 | |||
| 4029 | return 0; | 4047 | return 0; |
| 4030 | } | 4048 | } |
| 4031 | 4049 | ||
diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c index 9a96e17bf7cd..7fe2aa73cff6 100644 --- a/drivers/target/iscsi/iscsi_target_erl0.c +++ b/drivers/target/iscsi/iscsi_target_erl0.c | |||
| @@ -930,8 +930,10 @@ static void iscsit_handle_connection_cleanup(struct iscsi_conn *conn) | |||
| 930 | } | 930 | } |
| 931 | } | 931 | } |
| 932 | 932 | ||
| 933 | void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn) | 933 | void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn, bool *conn_freed) |
| 934 | { | 934 | { |
| 935 | *conn_freed = false; | ||
| 936 | |||
| 935 | spin_lock_bh(&conn->state_lock); | 937 | spin_lock_bh(&conn->state_lock); |
| 936 | if (atomic_read(&conn->connection_exit)) { | 938 | if (atomic_read(&conn->connection_exit)) { |
| 937 | spin_unlock_bh(&conn->state_lock); | 939 | spin_unlock_bh(&conn->state_lock); |
| @@ -942,6 +944,7 @@ void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn) | |||
| 942 | if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT) { | 944 | if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT) { |
| 943 | spin_unlock_bh(&conn->state_lock); | 945 | spin_unlock_bh(&conn->state_lock); |
| 944 | iscsit_close_connection(conn); | 946 | iscsit_close_connection(conn); |
| 947 | *conn_freed = true; | ||
| 945 | return; | 948 | return; |
| 946 | } | 949 | } |
| 947 | 950 | ||
| @@ -955,4 +958,5 @@ void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn) | |||
| 955 | spin_unlock_bh(&conn->state_lock); | 958 | spin_unlock_bh(&conn->state_lock); |
| 956 | 959 | ||
| 957 | iscsit_handle_connection_cleanup(conn); | 960 | iscsit_handle_connection_cleanup(conn); |
| 961 | *conn_freed = true; | ||
| 958 | } | 962 | } |
diff --git a/drivers/target/iscsi/iscsi_target_erl0.h b/drivers/target/iscsi/iscsi_target_erl0.h index 60e69e2af6ed..3822d9cd1230 100644 --- a/drivers/target/iscsi/iscsi_target_erl0.h +++ b/drivers/target/iscsi/iscsi_target_erl0.h | |||
| @@ -15,6 +15,6 @@ extern int iscsit_stop_time2retain_timer(struct iscsi_session *); | |||
| 15 | extern void iscsit_connection_reinstatement_rcfr(struct iscsi_conn *); | 15 | extern void iscsit_connection_reinstatement_rcfr(struct iscsi_conn *); |
| 16 | extern void iscsit_cause_connection_reinstatement(struct iscsi_conn *, int); | 16 | extern void iscsit_cause_connection_reinstatement(struct iscsi_conn *, int); |
| 17 | extern void iscsit_fall_back_to_erl0(struct iscsi_session *); | 17 | extern void iscsit_fall_back_to_erl0(struct iscsi_session *); |
| 18 | extern void iscsit_take_action_for_connection_exit(struct iscsi_conn *); | 18 | extern void iscsit_take_action_for_connection_exit(struct iscsi_conn *, bool *); |
| 19 | 19 | ||
| 20 | #endif /*** ISCSI_TARGET_ERL0_H ***/ | 20 | #endif /*** ISCSI_TARGET_ERL0_H ***/ |
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 66238477137b..92b96b51d506 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
| @@ -1464,5 +1464,9 @@ int iscsi_target_login_thread(void *arg) | |||
| 1464 | break; | 1464 | break; |
| 1465 | } | 1465 | } |
| 1466 | 1466 | ||
| 1467 | while (!kthread_should_stop()) { | ||
| 1468 | msleep(100); | ||
| 1469 | } | ||
| 1470 | |||
| 1467 | return 0; | 1471 | return 0; |
| 1468 | } | 1472 | } |
