[PATCH 5/5] fcoe: Only rmmod fcoe.ko if there are no active connections

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

 



From: Rob Love <robert.w.love@xxxxxxxxx>

Currently we're gracefully tearing down each active connection
when fcoe.ko is removed. We shouldn't allow the user to destroy
connections by removing the module. We should force the user to
destroy each connection and then the module can be removed.

This patch makes it so a refrerence count on the module is taken
each time a fcoe_interface is created. The reference count
is dropped when the fcoe_interface is destroyed. This makes it
so that module_exit() doesn't get called unless all fcoe_interfaces
have been destroyed.

This patch leaves the removal of interfaces in the module_exit
routine so that if the user does a 'rmmod -f' we'll clean everything
up before removing the module.

The module_put line was put before the out_putdev goto line because
we should only be decrementing the reference count if a
fcoe_interface is actually destroyed. If we can't find the netdev
or the fcoe_interface then it's assumed that something else has
destroyed the fcoe_interface and it would have decremented the
reference count at that time.

Signed-off-by: Robert Love <robert.w.love@xxxxxxxxx>
---

 drivers/scsi/fcoe/fcoe.c |   18 ++++++++++++++++--
 1 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 10be9f3..2f47ae7 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -2009,6 +2009,8 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
 	fcoe_interface_cleanup(fcoe);
 	rtnl_unlock();
 	fcoe_if_destroy(fcoe->ctlr.lp);
+	module_put(THIS_MODULE);
+
 out_putdev:
 	dev_put(netdev);
 out_nodev:
@@ -2059,6 +2061,11 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp)
 	}
 #endif
 
+	if (!try_module_get(THIS_MODULE)) {
+		rc = -EINVAL;
+		goto out_nomod;
+	}
+
 	rtnl_lock();
 	netdev = fcoe_if_to_netdev(buffer);
 	if (!netdev) {
@@ -2099,17 +2106,24 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp)
 	if (!fcoe_link_ok(lport))
 		fcoe_ctlr_link_up(&fcoe->ctlr);
 
-	rc = 0;
-out_free:
 	/*
 	 * Release from init in fcoe_interface_create(), on success lport
 	 * should be holding a reference taken in fcoe_if_create().
 	 */
 	fcoe_interface_put(fcoe);
+	dev_put(netdev);
+	rtnl_unlock();
+	mutex_unlock(&fcoe_config_mutex);
+
+	return 0;
+out_free:
+	fcoe_interface_put(fcoe);
 out_putdev:
 	dev_put(netdev);
 out_nodev:
 	rtnl_unlock();
+	module_put(THIS_MODULE);
+out_nomod:
 	mutex_unlock(&fcoe_config_mutex);
 	return rc;
 }

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[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