When iscsi conn gets closed, some tasks may be still processed in scsi layer, and can't be released immediatelly, thus their release is delayed. But the conn release should be delayed too. To do this we can increment conn refcount per each task in scsi. Thus the last conn_put() in conn_close() will not lead to the conn destruction. Then we decrement the refcount when the tasks complete and ensure that the conn is freed when the last such task returns from scsi. Signed-off-by: Alexander Nezhinsky <alexandern@xxxxxxxxxxxx> --- usr/iscsi/conn.c | 11 ++++++++++- usr/iscsi/iscsid.c | 8 +++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/usr/iscsi/conn.c b/usr/iscsi/conn.c index a3af6a4..fa4096c 100644 --- a/usr/iscsi/conn.c +++ b/usr/iscsi/conn.c @@ -173,8 +173,17 @@ void conn_close(struct iscsi_connection *conn) * This task is in SCSI. We need to wait for I/O * completion. */ - if (task_in_scsi(task)) + if (task_in_scsi(task)) { + /* We increment connection's refcount to allow + * the task to complete in scsi layer. + * Then we'll decrement it back and dispose of + * the connection when no such tasks remain. + */ + dprintf("task %" PRIx64 " in_scsi, release delayed\n", + task->tag); + conn_get(conn); continue; + } iscsi_free_task(task); } done: diff --git a/usr/iscsi/iscsid.c b/usr/iscsi/iscsid.c index 3a79d93..050047e 100644 --- a/usr/iscsi/iscsid.c +++ b/usr/iscsi/iscsid.c @@ -1184,9 +1184,15 @@ static int iscsi_scsi_cmd_done(uint64_t nid, int result, struct scsi_cmd *scmd) * We could delay the closing of the conn in some cases and send * the response with a little extra code or we can check if this * task got reassinged to another connection. + * When the connection was closing, its refcount got incremented + * for each in_scsi task whose release was delayed. + * Thus we need to decrement it back to enable proper + * connection and session release. */ - if (task->conn->state == STATE_CLOSE) { + if (task->conn->closed) { + dprintf("task %" PRIx64 " from scsi, releasing\n", task->tag); iscsi_free_cmd_task(task); + conn_put(task->conn); return 0; } -- 1.7.3.2 -- 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