@@ -620,17 +620,13 @@ static void iscsi_target_do_cleanup(struct work_struct *work)
struct sock *sk = conn->sock->sk;
struct iscsi_login *login = conn->login;
struct iscsi_np *np = login->np;
- struct iscsi_portal_group *tpg = conn->tpg;
- struct iscsi_tpg_np *tpg_np = conn->tpg_np;
pr_debug("Entering iscsi_target_do_cleanup\n");
cancel_delayed_work_sync(&conn->login_work);
conn->orig_state_change(sk);
-
iscsi_target_restore_sock_callbacks(conn);
- iscsi_target_login_drop(conn, login);
- iscsit_deaccess_np(np, tpg, tpg_np);
+ send_sig(SIGINT, np->np_thread, 1);
pr_debug("iscsi_target_do_cleanup done()\n");
}
We cannot free the connection in iscsi_target_do_cleanup because the np_thread could still be accessing it. An easy way to hit this bug is to force a command to get stuck and timeout. The initiator will send TMFs which will fail and then it drop the session and try to relogin. While the login thread waits in iscsit_cause_connection_reinstatement for the original connection's iscsit_close_connection call to iscsit_release_commands_from_conn to complete, the initiator could fail the login operation and kill the tcp connection. That will fire off iscsi_target_sk_state_change -> iscsi_target_do_cleanup which will free the connection. If the command gets unstuck then it will complete, and iscsit_cause_connection_reinstatement will return and np_thread will try to complete the login and access the freed connection. This patch has iscsi_target_do_cleanup do the low level socket state change and wake up the np_thread. When the np_thread wakes from iscsit_cause_connection_reinstatement it will see the tcp connection has been failed and the login will fail like normal. Signed-off-by: Mike Christie <mchristi@redhat.com> --- drivers/target/iscsi/iscsi_target_nego.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)