diff --git a/iscsi-scst/kernel/iscsi.h b/iscsi-scst/kernel/iscsi.h index c0e0d7764..ecd7dcfa5 100644 --- a/iscsi-scst/kernel/iscsi.h +++ b/iscsi-scst/kernel/iscsi.h @@ -122,6 +122,7 @@ struct iscsi_session { struct iscsi_session *sess_reinst_successor; unsigned int sess_reinstating:1; unsigned int sess_shutting_down:1; + unsigned int deleted_from_session_list:1; /* All don't need any protection */ char *initiator_name; diff --git a/iscsi-scst/kernel/nthread.c b/iscsi-scst/kernel/nthread.c index 8b8a4f48d..5cb1c67d9 100644 --- a/iscsi-scst/kernel/nthread.c +++ b/iscsi-scst/kernel/nthread.c @@ -552,6 +552,17 @@ static void close_conn(struct iscsi_conn *conn) if (list_empty(&session->conn_list)) { sBUG_ON(session->sess_reinst_successor != NULL); + + list_del(&session->session_list_entry); + session->deleted_from_session_list = 1; + + mutex_unlock(&target->target_mutex); + if (session->scst_sess != NULL) { + scst_unregister_session(session->scst_sess, 1, NULL); + session->scst_sess = NULL; + } + mutex_lock(&target->target_mutex); + session_free(session); } diff --git a/iscsi-scst/kernel/session.c b/iscsi-scst/kernel/session.c index 39e05c618..6a54100c0 100644 --- a/iscsi-scst/kernel/session.c +++ b/iscsi-scst/kernel/session.c @@ -215,8 +215,7 @@ int session_free(struct iscsi_session *session) for (i = 0; i < ARRAY_SIZE(session->cmnd_hash); i++) sBUG_ON(!list_empty(&session->cmnd_hash[i])); - if (session->scst_sess != NULL) - scst_unregister_session(session->scst_sess, 1, NULL); + sBUG_ON(session->scst_sess != NULL); if (session->sess_reinst_successor != NULL) sess_enable_reinstated_sess(session->sess_reinst_successor); @@ -233,7 +232,8 @@ int session_free(struct iscsi_session *session) } } - list_del(&session->session_list_entry); + if (!session->deleted_from_session_list) + list_del(&session->session_list_entry); kfree(session->initiator_name); kfree(session); @@ -267,10 +267,10 @@ static void iscsi_session_info_show(struct seq_file *seq, list_for_each_entry(session, &target->session_list, session_list_entry) { - seq_printf(seq, "\tsid:%llx initiator:%s reinstating %d\n", + seq_printf(seq, "\tsid:%llx initiator:%s (reinstating %s)\n", (long long unsigned int)session->sid, session->initiator_name, - session->sess_reinstating); + session->sess_reinstating ? "yes" : "no"); conn_info_show(seq, session); } return;