diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 466815094..6fe04b6ba 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -5027,8 +5027,7 @@ static void scst_clear_reservation(struct scst_tgt_dev *tgt_dev) } struct scst_session *scst_alloc_session(struct scst_tgt *tgt, gfp_t gfp_mask, - const char *name, - const char *initiator_name) + const char *initiator_name) { struct scst_session *sess; int i; @@ -5064,22 +5063,16 @@ struct scst_session *scst_alloc_session(struct scst_tgt *tgt, gfp_t gfp_mask, spin_lock_init(&sess->lat_lock); #endif - sess->name = kstrdup(name, gfp_mask); - if (!sess->name) - goto out_free; - sess->initiator_name = kstrdup(initiator_name, gfp_mask); if (sess->initiator_name == NULL) { PRINT_ERROR("%s", "Unable to dup sess->initiator_name"); - goto out_free_sess_name; + goto out_free; } out: TRACE_EXIT(); return sess; -out_free_sess_name: - kfree(sess->name); out_free: kmem_cache_free(scst_sess_cachep, sess); sess = NULL; @@ -5122,7 +5115,8 @@ void scst_free_session(struct scst_session *sess) kfree(sess->transport_id); kfree(sess->initiator_name); - kfree(sess->name); + if (sess->name != sess->initiator_name) + kfree(sess->name); kmem_cache_free(scst_sess_cachep, sess); diff --git a/scst/src/scst_priv.h b/scst/src/scst_priv.h index 56c37c32b..1b360d8ad 100644 --- a/scst/src/scst_priv.h +++ b/scst/src/scst_priv.h @@ -348,7 +348,6 @@ int scst_assign_dev_handler(struct scst_device *dev, struct scst_dev_type *handler); struct scst_session *scst_alloc_session(struct scst_tgt *tgt, gfp_t gfp_mask, - const char *name, const char *initiator_name); void scst_free_session(struct scst_session *sess); void scst_free_session_callback(struct scst_session *sess); diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index b6821a6b9..030857bbd 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -6412,6 +6412,42 @@ bool scst_initiator_has_luns(struct scst_tgt *tgt, const char *initiator_name) } EXPORT_SYMBOL_GPL(scst_initiator_has_luns); +static char *scst_get_unique_sess_name(struct list_head *sess_list, + const char* initiator_name) +{ + char *name = (char *)initiator_name; + struct scst_session *s; + int len = 0, n = 1; + + BUG_ON(!initiator_name); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) + lockdep_assert_held(&scst_mutex); +#endif + +restart: + list_for_each_entry(s, sess_list, sess_list_entry) { + if (s->name && strcmp(name, s->name) == 0) { + TRACE_DBG("Duplicated session from the same initiator " + "%s found", name); + + if (name == initiator_name) { + len = strlen(initiator_name) + 20; + name = kmalloc(len, GFP_KERNEL); + if (name == NULL) { + PRINT_ERROR("Unable to allocate a " + "replacement name (size %d)", + len); + } + } + + snprintf(name, len, "%s_%d", initiator_name, n); + n++; + goto restart; + } + } + return name; +} + static int scst_init_session(struct scst_session *sess) { int res = 0; @@ -6448,6 +6484,12 @@ static int scst_init_session(struct scst_session *sess) sess->transport_id), sess->tgt->rel_tgt_id); } + res = -ENOMEM; + sess->name = scst_get_unique_sess_name(&sess->tgt->sess_list, + sess->initiator_name); + if (!sess->name) + goto failed; + res = scst_sess_sysfs_create(sess); if (res != 0) goto failed; @@ -6513,37 +6555,6 @@ restart: return res; } -static char *scst_get_unique_sess_name(struct list_head *sess_list, - const char* initiator_name) -{ - char *name = (char *)initiator_name; - struct scst_session *s; - int len = 0, n = 1; - -restart: - list_for_each_entry(s, sess_list, sess_list_entry) { - if (strcmp(name, s->name) == 0) { - TRACE_DBG("Duplicated session from the same initiator " - "%s found", name); - - if (name == initiator_name) { - len = strlen(initiator_name) + 20; - name = kmalloc(len, GFP_KERNEL); - if (name == NULL) { - PRINT_ERROR("Unable to allocate a " - "replacement name (size %d)", - len); - } - } - - snprintf(name, len, "%s_%d", initiator_name, n); - n++; - goto restart; - } - } - return name; -} - /** * scst_register_session() - register session * @tgt: target @@ -6591,19 +6602,14 @@ struct scst_session *scst_register_session(struct scst_tgt *tgt, int atomic, const char *initiator_name, void *tgt_priv, void *result_fn_data, void (*result_fn) (struct scst_session *sess, void *data, int result)) { - struct scst_session *sess = NULL; - char *name; + struct scst_session *sess; int res; unsigned long flags; TRACE_ENTRY(); - name = scst_get_unique_sess_name(&tgt->sess_list, initiator_name); - if (!name) - goto out; - sess = scst_alloc_session(tgt, atomic ? GFP_ATOMIC : GFP_KERNEL, - name, initiator_name); + initiator_name); if (sess == NULL) goto out; @@ -6628,8 +6634,6 @@ struct scst_session *scst_register_session(struct scst_tgt *tgt, int atomic, } out: - if (name != initiator_name) - kfree(name); TRACE_EXIT(); return sess;