Fix for circular locking dependency between target_mutex and scst_mutex spotted by lockdep

git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@743 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2009-04-03 17:38:20 +00:00
parent 25a289c0f6
commit f8eebf8dd8
3 changed files with 27 additions and 14 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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 */