From 167a7bafa5b9d7d6ef6cb36dd0ab1e888a3fd1f6 Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Thu, 26 Jan 2012 05:00:28 +0000 Subject: [PATCH] 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 --- qla2x00t/qla2x00-target/qla2x00t.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/qla2x00t/qla2x00-target/qla2x00t.c b/qla2x00t/qla2x00-target/qla2x00t.c index f098e0c62..0506737ac 100644 --- a/qla2x00t/qla2x00-target/qla2x00t.c +++ b/qla2x00t/qla2x00-target/qla2x00t.c @@ -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);