Skip to content

Commit bc3d12b

Browse files
hreineckemartinkpetersen
authored andcommitted
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: a407c59 ("scsi: libfc: Fixup disc_mutex handling") Signed-off-by: Hannes Reinecke <hare@suse.com> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 9a26653 commit bc3d12b

File tree

1 file changed

+4
-6
lines changed

1 file changed

+4
-6
lines changed

drivers/scsi/libfc/fc_disc.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,16 @@ static void fc_disc_restart(struct fc_disc *);
6262
*/
6363
static void fc_disc_stop_rports(struct fc_disc *disc)
6464
{
65-
struct fc_lport *lport;
6665
struct fc_rport_priv *rdata;
6766

68-
lport = fc_disc_lport(disc);
69-
lockdep_assert_held(&lport->lp_mutex);
67+
lockdep_assert_held(&disc->disc_mutex);
7068

71-
rcu_read_lock();
72-
list_for_each_entry_rcu(rdata, &disc->rports, peers) {
69+
list_for_each_entry(rdata, &disc->rports, peers) {
7370
if (kref_get_unless_zero(&rdata->kref)) {
7471
fc_rport_logoff(rdata);
7572
kref_put(&rdata->kref, fc_rport_destroy);
7673
}
7774
}
78-
rcu_read_unlock();
7975
}
8076

8177
/**
@@ -699,7 +695,9 @@ static void fc_disc_stop(struct fc_lport *lport)
699695

700696
if (disc->pending)
701697
cancel_delayed_work_sync(&disc->disc_work);
698+
mutex_lock(&disc->disc_mutex);
702699
fc_disc_stop_rports(disc);
700+
mutex_unlock(&disc->disc_mutex);
703701
}
704702

705703
/**

0 commit comments

Comments
 (0)