[PATCH 2/3] guard iser connection from release while tasks are in scsi

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Added connection's ref.count increment before iser submits a command
to scsi, and decrement when the task is completed by whatever reason
including disconnect. Guards connection from release while some tasks
are still in scsi. Must be handled by iser code explicitly because
iser and iscsi pass thru different flow paths during command completion.

Signed-off-by: Alexander Nezhinsky <alexandern@xxxxxxxxxxxx>
---
 usr/iscsi/iser.c |   25 ++++++++++++++++---------
 1 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/usr/iscsi/iser.c b/usr/iscsi/iser.c
index 5d56e07..983a70f 100644
--- a/usr/iscsi/iser.c
+++ b/usr/iscsi/iser.c
@@ -753,29 +753,31 @@ static void iser_task_free_in_bufs(struct iser_task *task)
 
 static void iser_complete_task(struct iser_task *task)
 {
+	struct iser_conn *conn = task->conn;
+
 	if (unlikely(task->opcode != ISCSI_OP_SCSI_CMD)) {
 		dprintf("task:%p, non-cmd\n", task);
 		return;
 	}
 
+	list_del(&task->session_list);
+	if (task->is_read)
+		iser_task_free_in_bufs(task);
+	if (task->is_write) {
+		iser_task_free_out_bufs(task);
+		/* iser_task_free_dout_tasks(task); // ToDo: multiple out buffers */
+	}
+
 	/* we are completing scsi cmd task, returning from target */
 	if (likely(task_in_scsi(task))) {
 		target_cmd_done(&task->scmd);
 		clear_task_in_scsi(task);
+		iser_conn_put(conn);
 	}
 	if (task->extdata) {
 		free(task->extdata);
 		task->extdata = NULL;
 	}
-
-	list_del(&task->session_list);
-	if (task->is_read)
-		iser_task_free_in_bufs(task);
-	if (task->is_write) {
-		iser_task_free_out_bufs(task);
-		/* iser_task_free_dout_tasks(task); // ToDo: multiple out buffers */
-	}
-	dprintf("task:%p\n", task);
 }
 
 static char *iser_conn_login_phase_name(enum iser_login_phase phase)
@@ -1819,12 +1821,15 @@ static int iser_tm_exec(struct iser_task *task)
 					  (unsigned long) task, fn, req_bhs->lun,
 					  req_bhs->rtt, 0);
 		set_task_in_scsi(task);
+		iser_conn_get(conn);
+
 		switch (ret) {
 		case MGMT_REQ_QUEUED:
 			break;
 		case MGMT_REQ_FAILED:
 		case MGMT_REQ_DONE:
 			clear_task_in_scsi(task);
+			iser_conn_put(conn);
 			break;
 		}
 	}
@@ -1962,6 +1967,8 @@ static void iser_scsi_cmd_iosubmit(struct iser_task *task)
 	dprintf("task:%p tag:0x%04"PRIx64 "\n", task, task->tag);
 
 	set_task_in_scsi(task);
+	iser_conn_get(conn);
+
 	target_cmd_queue(session->target->tid, scmd);
 }
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]

  Powered by Linux