From e207090233fdfe6b10fed125102a1ab6bd864017 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 29 Jul 2012 14:09:42 +0000 Subject: [PATCH] Fix race between q2t_del_sess_work_fn() and q2t_clear_tgt_db() (merge r4101 from trunk) git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/2.2.x@4434 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 6b1a1b284..89b511ee5 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, sess->expires - jiffies);