diff mbox

[1/4] iscsi target: make iscsit_stop_session interruptible

Message ID 1488164640-8751-2-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
To handle initiators dropping tcp connections while the login
process is waiting on a connection getting cleaned up, we need
to make that login path interruptible, so we do not have to wait
for long periods of time and let relogins pile up.

This patch modifies iscsit_stop_connection, so it can be woken up and
return failure. We want to use it in the login path. I am not sure
if it is needed in other paths. I was thinking it might be useful
in the configfs path, but I think that will take more work.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/target/iscsi/iscsi_target.c          | 18 ++++++++++++------
 drivers/target/iscsi/iscsi_target.h          |  2 +-
 drivers/target/iscsi/iscsi_target_configfs.c |  2 +-
 drivers/target/iscsi/iscsi_target_login.c    |  5 ++++-
 4 files changed, 18 insertions(+), 9 deletions(-)
diff mbox

Patch

diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 2285988..4328036 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -4280,7 +4280,7 @@  int iscsit_close_connection(
 		if (!atomic_read(&sess->session_stop_active)) {
 			atomic_set(&sess->session_stop_active, 1);
 			spin_unlock_bh(&sess->conn_lock);
-			iscsit_stop_session(sess, 0, 0);
+			iscsit_stop_session(sess, 0, 0, 0);
 			return 0;
 		}
 		spin_unlock_bh(&sess->conn_lock);
@@ -4371,7 +4371,7 @@  int iscsit_close_session(struct iscsi_session *sess)
 	 */
 	if (!in_interrupt()) {
 		if (iscsit_check_session_usage_count(sess) == 1)
-			iscsit_stop_session(sess, 1, 1);
+			iscsit_stop_session(sess, 1, 1, 0);
 	} else {
 		if (iscsit_check_session_usage_count(sess) == 2) {
 			atomic_set(&sess->session_logout, 0);
@@ -4432,7 +4432,7 @@  static void iscsit_logout_post_handler_closesession(
 	complete(&conn->conn_logout_comp);
 
 	iscsit_dec_conn_usage_count(conn);
-	iscsit_stop_session(sess, sleep, sleep);
+	iscsit_stop_session(sess, sleep, sleep, 0);
 	iscsit_dec_session_usage_count(sess);
 	iscsit_close_session(sess);
 }
@@ -4609,10 +4609,11 @@  int iscsit_free_session(struct iscsi_session *sess)
 	return 0;
 }
 
-void iscsit_stop_session(
+int iscsit_stop_session(
 	struct iscsi_session *sess,
 	int session_sleep,
-	int connection_sleep)
+	int connection_sleep,
+	int interruptible)
 {
 	u16 conn_count = atomic_read(&sess->nconn);
 	struct iscsi_conn *conn, *conn_tmp = NULL;
@@ -4652,9 +4653,14 @@  void iscsit_stop_session(
 
 	if (session_sleep && atomic_read(&sess->nconn)) {
 		spin_unlock_bh(&sess->conn_lock);
-		wait_for_completion(&sess->session_wait_comp);
+		if (interruptible)
+			return wait_for_completion_interruptible(&sess->session_wait_comp);
+		else
+			wait_for_completion(&sess->session_wait_comp);
+
 	} else
 		spin_unlock_bh(&sess->conn_lock);
+	return 0;
 }
 
 int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *tpg, int force)
diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h
index e0db2ce..1e7cf3d 100644
--- a/drivers/target/iscsi/iscsi_target.h
+++ b/drivers/target/iscsi/iscsi_target.h
@@ -43,7 +43,7 @@  extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *,
 extern int iscsit_close_session(struct iscsi_session *);
 extern void iscsit_fail_session(struct iscsi_session *);
 extern int iscsit_free_session(struct iscsi_session *);
-extern void iscsit_stop_session(struct iscsi_session *, int, int);
+extern int iscsit_stop_session(struct iscsi_session *, int, int, int);
 extern int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *, int);
 
 extern struct iscsit_global *iscsit_global;
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
index bf40f03..fee07c6 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -1536,7 +1536,7 @@  static void lio_tpg_close_session(struct se_session *se_sess)
 	iscsit_stop_time2retain_timer(sess);
 	spin_unlock_bh(&se_tpg->session_lock);
 
-	iscsit_stop_session(sess, 1, 1);
+	iscsit_stop_session(sess, 1, 1, 0);
 	iscsit_close_session(sess);
 }
 
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index 303cb65..d7d406e 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -176,6 +176,7 @@  int iscsi_check_for_session_reinstatement(struct iscsi_conn *conn)
 	struct iscsi_session *sess = NULL, *sess_p = NULL;
 	struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
 	struct se_session *se_sess, *se_sess_tmp;
+	int ret;
 
 	initiatorname_param = iscsi_find_param_from_key(
 			INITIATORNAME, conn->param_list);
@@ -235,8 +236,10 @@  int iscsi_check_for_session_reinstatement(struct iscsi_conn *conn)
 	}
 	spin_unlock_bh(&sess->conn_lock);
 
-	iscsit_stop_session(sess, 1, 1);
+	ret = iscsit_stop_session(sess, 1, 1, 1);
 	iscsit_dec_session_usage_count(sess);
+	if (ret)
+		return -1;
 
 	iscsit_close_session(sess);
 	return 0;