diff --git a/iscsi-scst/kernel/config.c b/iscsi-scst/kernel/config.c index b4294c2fc..87961c6cd 100644 --- a/iscsi-scst/kernel/config.c +++ b/iscsi-scst/kernel/config.c @@ -265,7 +265,7 @@ static int del_conn(struct iscsi_target *target, void __user *ptr) return conn_del(session, &info); } -/* target_mutex supposed to be locked */ +/* target_mgmt_mutex supposed to be locked */ static int add_session(struct iscsi_target *target, void __user *ptr) { int err; @@ -419,6 +419,9 @@ static long ioctl(struct file *file, unsigned int cmd, unsigned long arg) case ADD_TARGET: err = add_target((void __user *) arg); goto out_unlock; + case ADD_SESSION: + err = add_session(target, (void __user *) arg); + goto out_unlock; } if (!target) { @@ -430,10 +433,6 @@ static long ioctl(struct file *file, unsigned int cmd, unsigned long arg) mutex_lock(&target->target_mutex); switch (cmd) { - case ADD_SESSION: - err = add_session(target, (void __user *) arg); - break; - case DEL_SESSION: err = del_session(target, (void __user *) arg); break; diff --git a/iscsi-scst/kernel/iscsi.h b/iscsi-scst/kernel/iscsi.h index ecd7dcfa5..4255d61c0 100644 --- a/iscsi-scst/kernel/iscsi.h +++ b/iscsi-scst/kernel/iscsi.h @@ -72,7 +72,7 @@ struct iscsi_target { struct list_head session_list; /* protected by target_mutex */ - /* Both protected by target_mutex */ + /* Both protected by target_mgmt_mutex */ struct iscsi_trgt_param trgt_param; /* * Put here to have uniform parameters checking and assigning diff --git a/iscsi-scst/kernel/session.c b/iscsi-scst/kernel/session.c index 6a54100c0..a9083c429 100644 --- a/iscsi-scst/kernel/session.c +++ b/iscsi-scst/kernel/session.c @@ -29,7 +29,7 @@ struct iscsi_session *session_lookup(struct iscsi_target *target, u64 sid) return NULL; } -/* target_mutex supposed to be locked */ +/* target_mgmt_mutex supposed to be locked */ static int iscsi_session_alloc(struct iscsi_target *target, struct iscsi_kern_session_info *info, struct iscsi_session **result) { @@ -91,8 +91,6 @@ static int iscsi_session_alloc(struct iscsi_target *target, scst_sess_set_tgt_priv(session->scst_sess, session); - list_add_tail(&session->session_list_entry, &target->session_list); - TRACE_MGMT_DBG("Session %p created: target %p, tid %u, sid %#Lx", session, target, target->tid, info->sid); @@ -149,22 +147,28 @@ static void session_reinstate(struct iscsi_session *old_sess, return; } -/* target_mutex supposed to be locked */ +/* target_mgmt_mutex supposed to be locked */ int session_add(struct iscsi_target *target, struct iscsi_kern_session_info *info) { - struct iscsi_session *session, *old_sess; + struct iscsi_session *new_sess, *session, *old_sess; int err = 0; union iscsi_sid sid; TRACE_MGMT_DBG("Adding session SID %llx", info->sid); + err = iscsi_session_alloc(target, info, &new_sess); + if (err != 0) + goto out; + + mutex_lock(&target->target_mutex); + session = session_lookup(target, info->sid); if (session) { PRINT_ERROR("Attempt to add session with existing SID %llx", info->sid); err = -EEXIST; - goto out; + goto out_err_unlock; } sid = *(union iscsi_sid *)&info->sid; @@ -189,12 +193,22 @@ int session_add(struct iscsi_target *target, } } - err = iscsi_session_alloc(target, info, &session); - if ((err == 0) && (old_sess != NULL)) + session = new_sess; + list_add_tail(&session->session_list_entry, &target->session_list); + + if (old_sess != NULL) session_reinstate(old_sess, session); +out_unlock: + mutex_unlock(&target->target_mutex); + out: return err; + +out_err_unlock: + new_sess->deleted_from_session_list = 1; + session_free(new_sess); + goto out_unlock; } /* target_mutex supposed to be locked */