mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-20 20:21:30 +00:00
scst: Make sure that scst_get_unique_sess_name() is called under scst_mutex
such that session names are again guaranteed to be unique (follow-up for r4452). git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@4454 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user