diff --git a/scst/include/scst.h b/scst/include/scst.h index a75930079..acaafa4a0 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -1488,6 +1488,12 @@ struct scst_tgt { /* List of remote sessions per target, protected by scst_mutex */ struct list_head sess_list; + /* + * List of remote sessions registered in sysfs per target, protected + * by scst_mutex. + */ + struct list_head sysfs_sess_list; + /* List entry of targets per template (tgts_list) */ struct list_head tgt_list_entry; @@ -1674,6 +1680,9 @@ struct scst_session { /* List entry of sessions per target */ struct list_head sess_list_entry; + /* Per target list entry for sessions registered in sysfs. */ + struct list_head sysfs_sess_list_entry; + /* List entry for the list that keeps session, waiting for the init */ struct list_head sess_init_list_entry; diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index c11b7cbb3..d1f0c3c87 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -3291,6 +3291,7 @@ int scst_alloc_tgt(struct scst_tgt_template *tgtt, struct scst_tgt **tgt) } INIT_LIST_HEAD(&t->sess_list); + INIT_LIST_HEAD(&t->sysfs_sess_list); init_waitqueue_head(&t->unreg_waitQ); t->tgtt = tgtt; t->sg_tablesize = tgtt->sg_tablesize; @@ -5107,6 +5108,8 @@ void scst_free_session(struct scst_session *sess) mutex_lock(&scst_mutex); + list_del(&sess->sysfs_sess_list_entry); + /* Called under lock to protect from too early tgt release */ wake_up_all(&sess->tgt->unreg_waitQ); diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 9b0276123..6115555b3 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -6440,7 +6440,7 @@ bool scst_initiator_has_luns(struct scst_tgt *tgt, const char *initiator_name) EXPORT_SYMBOL_GPL(scst_initiator_has_luns); /* Supposed to be called under scst_mutex */ -static char *scst_get_unique_sess_name(struct list_head *sess_list, +static char *scst_get_unique_sess_name(struct list_head *sysfs_sess_list, const char *initiator_name) { char *name = (char *)initiator_name; @@ -6453,8 +6453,9 @@ static char *scst_get_unique_sess_name(struct list_head *sess_list, #endif restart: - list_for_each_entry(s, sess_list, sess_list_entry) { - if (s->sess_name && strcmp(name, s->sess_name) == 0) { + list_for_each_entry(s, sysfs_sess_list, sysfs_sess_list_entry) { + BUG_ON(!s->sess_name); + if (strcmp(name, s->sess_name) == 0) { TRACE_DBG("Duplicated session from the same initiator " "%s found", name); @@ -6498,6 +6499,8 @@ static int scst_init_session(struct scst_session *sess) TRACE_DBG("Adding sess %p to tgt->sess_list", sess); list_add_tail(&sess->sess_list_entry, &sess->tgt->sess_list); + INIT_LIST_HEAD(&sess->sysfs_sess_list_entry); + if (sess->tgt->tgtt->get_initiator_port_transport_id != NULL) { res = sess->tgt->tgtt->get_initiator_port_transport_id( sess->tgt, sess, &sess->transport_id); @@ -6513,7 +6516,7 @@ static int scst_init_session(struct scst_session *sess) } res = -ENOMEM; - sess->sess_name = scst_get_unique_sess_name(&sess->tgt->sess_list, + sess->sess_name = scst_get_unique_sess_name(&sess->tgt->sysfs_sess_list, sess->initiator_name); if (!sess->sess_name) goto failed; @@ -6522,6 +6525,9 @@ static int scst_init_session(struct scst_session *sess) if (res != 0) goto failed; + list_add_tail(&sess->sysfs_sess_list_entry, + &sess->tgt->sysfs_sess_list); + /* * scst_sess_alloc_tgt_devs() must be called after session added in the * sess_list to not race with scst_check_reassign_sess()!