[SCSI] libfcoe: clean up netdev mapping properly when the transport goes away
authorYi Zou <yi.zou@intel.com>
Fri, 1 Apr 2011 23:06:19 +0000 (16:06 -0700)
committerJames Bottomley <James.Bottomley@suse.de>
Sun, 1 May 2011 15:20:42 +0000 (10:20 -0500)
When rmmoving the underlying fcoe transport driver module by force when
it's attached and in use, the correspoding netdev mapping should be
cleaned up properly as well, otherwise the lookup for a given netdev
for the transport would still return non NULL pointer, causing "unable
to handle paging request" bug.

Signed-off-by: Yi Zou <yi.zou@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
drivers/scsi/fcoe/fcoe_transport.c

index 7b61d00f5c43480a812c179f23012914af8bba09..ec0f395263c5b2f7650d5f6123eaf2a90a6ed2e8 100644 (file)
@@ -343,6 +343,7 @@ EXPORT_SYMBOL(fcoe_transport_attach);
 int fcoe_transport_detach(struct fcoe_transport *ft)
 {
        int rc = 0;
+       struct fcoe_netdev_mapping *nm = NULL, *tmp;
 
        mutex_lock(&ft_mutex);
        if (!ft->attached) {
@@ -352,6 +353,19 @@ int fcoe_transport_detach(struct fcoe_transport *ft)
                goto out_attach;
        }
 
+       /* remove netdev mapping for this transport as it is going away */
+       mutex_lock(&fn_mutex);
+       list_for_each_entry_safe(nm, tmp, &fcoe_netdevs, list) {
+               if (nm->ft == ft) {
+                       LIBFCOE_TRANSPORT_DBG("transport %s going away, "
+                               "remove its netdev mapping for %s\n",
+                               ft->name, nm->netdev->name);
+                       list_del(&nm->list);
+                       kfree(nm);
+               }
+       }
+       mutex_unlock(&fn_mutex);
+
        list_del(&ft->list);
        ft->attached = false;
        LIBFCOE_TRANSPORT_DBG("detaching transport %s\n", ft->name);