Fix race for sess between q2t_del_sess_work_fn() and q2t_clear_tgt_db() as well as other similar places

git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@4101 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2012-01-26 05:00:28 +00:00
parent 40ff4978ab
commit 167a7bafa5

View File

@@ -1045,6 +1045,14 @@ static void q2t_del_sess_work_fn(struct delayed_work *work)
q2t_undelete_sess(sess);
/*
* We need to take extra reference, because we are
* going to drop hardware_lock. Otherwise, we are racing
* with other possible calles of q2t_sess_put() for
* the same sess, e.g. by q2t_clear_tgt_db().
*/
q2t_sess_get(sess);
spin_unlock_irqrestore(&pha->hardware_lock, flags);
cancel = q2t_check_fcport_exist(ha, sess);
spin_lock_irqsave(&pha->hardware_lock, flags);
@@ -1055,7 +1063,7 @@ static void q2t_del_sess_work_fn(struct delayed_work *work)
* sess was again deleted while we were
* discovering it
*/
continue;
goto put_continue;
}
PRINT_INFO("qla2x00t(%ld): cancel deletion of "
@@ -1073,6 +1081,8 @@ static void q2t_del_sess_work_fn(struct delayed_work *work)
"deleted", sess);
q2t_sess_put(sess);
}
put_continue:
q2t_sess_put(sess);
} else {
schedule_delayed_work(&tgt->sess_del_work,
jiffies - sess->expires);