diff mbox

[3/4] iscsi target: don't free connection from iscsi_target_do_cleanup

Message ID 1488164640-8751-4-git-send-email-mchristi@redhat.com (mailing list archive)
State Superseded
Headers show

Commit Message

Mike Christie Feb. 27, 2017, 3:03 a.m. UTC
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(-)
diff mbox


diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c
index 5269e9e..9edac16 100644
--- a/drivers/target/iscsi/iscsi_target_nego.c
+++ b/drivers/target/iscsi/iscsi_target_nego.c
@@ -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");
-	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");