[PATCH 2/4] libfc: hold disc_mutex in fc_disc_stop_rports()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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: a407c593398c ("scsi: libfc: Fixup disc_mutex handling")
Signed-off-by: Hannes Reinecke <hare@xxxxxxxx>
---
 drivers/scsi/libfc/fc_disc.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
index c1756b9b3ea5..f969a71348ef 100644
--- a/drivers/scsi/libfc/fc_disc.c
+++ b/drivers/scsi/libfc/fc_disc.c
@@ -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);
 }
 
 /**
-- 
2.12.3




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux