From 736b99485d4074519de43d0a26e03aed04e051ad Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 7 Aug 2012 17:28:34 +0000 Subject: [PATCH] scst: Move the code for computing a unique session name git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@4452 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/include/scst.h | 3 +++ scst/src/scst_lib.c | 12 ++++++++++-- scst/src/scst_priv.h | 3 ++- scst/src/scst_sysfs.c | 43 +++++-------------------------------------- scst/src/scst_targ.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 60 insertions(+), 43 deletions(-) diff --git a/scst/include/scst.h b/scst/include/scst.h index 716f6c768..c848e99e6 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -1662,6 +1662,9 @@ struct scst_session { /* Name of attached initiator */ const char *initiator_name; + /* Session name: initiator name + optional _%d. */ + const char *name; + /* List entry of sessions per target */ struct list_head sess_list_entry; diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index b4565c268..c749dc684 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -5027,7 +5027,8 @@ 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 *initiator_name) + const char *name, + const char *initiator_name) { struct scst_session *sess; int i; @@ -5063,16 +5064,22 @@ 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; + goto out_free_sess_name; } out: TRACE_EXIT(); return sess; +out_free_sess_name: + kfree(sess->name); out_free: kmem_cache_free(scst_sess_cachep, sess); sess = NULL; @@ -5121,6 +5128,7 @@ void scst_free_session(struct scst_session *sess) kfree(sess->transport_id); kfree(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 af18bbd4d..56c37c32b 100644 --- a/scst/src/scst_priv.h +++ b/scst/src/scst_priv.h @@ -348,7 +348,8 @@ 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 *initiator_name); + 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_sysfs.c b/scst/src/scst_sysfs.c index 29d38d37f..84770fda3 100644 --- a/scst/src/scst_sysfs.c +++ b/scst/src/scst_sysfs.c @@ -3598,48 +3598,18 @@ int scst_recreate_sess_luns_link(struct scst_session *sess) int scst_sess_sysfs_create(struct scst_session *sess) { int res = 0; - struct scst_session *s; - char *name = (char *)sess->initiator_name; - int len = strlen(name) + 1, n = 1; + const char *name; TRACE_ENTRY(); -restart: - list_for_each_entry(s, &sess->tgt->sess_list, sess_list_entry) { - if (!s->sess_kobj_ready) - continue; - - if (strcmp(name, kobject_name(&s->sess_kobj)) == 0) { - if (s == sess) - continue; - - TRACE_DBG("Duplicated session from the same initiator " - "%s found", name); - - if (name == sess->initiator_name) { - len = strlen(sess->initiator_name); - len += 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", sess->initiator_name, n); - n++; - goto restart; - } - } - + name = sess->name; TRACE_DBG("Adding session %s to sysfs", name); res = kobject_init_and_add(&sess->sess_kobj, &scst_session_ktype, sess->tgt->tgt_sess_kobj, name); if (res != 0) { PRINT_ERROR("Can't add session %s to sysfs", name); - goto out_free; + goto out; } sess->sess_kobj_ready = 1; @@ -3659,10 +3629,7 @@ restart: goto out_del; } -out_free: - if (name != sess->initiator_name) - kfree(name); - +out: TRACE_EXIT_RES(res); return res; @@ -3670,7 +3637,7 @@ out_del: kobject_del(&sess->sess_kobj); kobject_put(&sess->sess_kobj); sess->sess_kobj_ready = 0; - goto out_free; + goto out; } /* diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index f0571854c..b6821a6b9 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -6513,6 +6513,37 @@ 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 @@ -6560,14 +6591,19 @@ 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; + struct scst_session *sess = NULL; + char *name; 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, - initiator_name); + name, initiator_name); if (sess == NULL) goto out; @@ -6592,6 +6628,8 @@ struct scst_session *scst_register_session(struct scst_tgt *tgt, int atomic, } out: + if (name != initiator_name) + kfree(name); TRACE_EXIT(); return sess;