提交 bc3d12b7 编写于 作者: H Hannes Reinecke 提交者: Martin K. Petersen

scsi: libfc: hold disc_mutex in fc_disc_stop_rports()

fc_disc_stop_rports() is calling fc_rport_logoff(), which in turn is
acquiring the rport mutex. So we cannot use RCU list traversal here, but
rather need to hold the disc mutex to avoid list corruption while
traversing.

Fixes: a407c593 ("scsi: libfc: Fixup disc_mutex handling")
Signed-off-by: NHannes Reinecke <hare@suse.com>
Reviewed-by: NJohannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
上级 9a26653b
......@@ -62,20 +62,16 @@ static void fc_disc_restart(struct fc_disc *);
*/
static void fc_disc_stop_rports(struct fc_disc *disc)
{
struct fc_lport *lport;
struct fc_rport_priv *rdata;
lport = fc_disc_lport(disc);
lockdep_assert_held(&lport->lp_mutex);
lockdep_assert_held(&disc->disc_mutex);
rcu_read_lock();
list_for_each_entry_rcu(rdata, &disc->rports, peers) {
list_for_each_entry(rdata, &disc->rports, peers) {
if (kref_get_unless_zero(&rdata->kref)) {
fc_rport_logoff(rdata);
kref_put(&rdata->kref, fc_rport_destroy);
}
}
rcu_read_unlock();
}
/**
......@@ -699,7 +695,9 @@ static void fc_disc_stop(struct fc_lport *lport)
if (disc->pending)
cancel_delayed_work_sync(&disc->disc_work);
mutex_lock(&disc->disc_mutex);
fc_disc_stop_rports(disc);
mutex_unlock(&disc->disc_mutex);
}
/**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册