aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe
diff options
context:
space:
mode:
authorRobert Love <robert.w.love@intel.com>2011-01-28 19:03:47 -0500
committerJames Bottomley <James.Bottomley@suse.de>2011-02-12 11:59:30 -0500
commit7287fb9114096503eddfffb7b2ed691c809a6106 (patch)
tree416689671a8c97792ef481f29b0e2031bbab789d /drivers/scsi/fcoe
parent6da92d3463cd60f5b804475f70f659dc07331929 (diff)
[SCSI] fcoe: Fix module reference count for vports
vports are not grabbing module references but are releasing them. This causes the module reference count to decrement too many times and it wraps around past 0. The solution is to do a module_put() in fcoe_interface_release() so that the reference is only released when the fcoe_interface is released. There is a one-to-one relationship between the N_Port and the fcoe_interface, so the module reference will only be dropped when the N_Port is destroyed To create symetry in the code this patch moves the try_module_get() call into fcoe_interface_create(). This means that only the N_Port will grab a reference to the module when its corresponding fcoe_interface is created. This patch also makes it so that the fcoe_interface_create() routine encodes any error codes in the fcoe_interface pointer returned. This way its caller, fcoe_create(), can return an accurate error code. Signed-off-by: Robert Love <robert.w.love@intel.com> Tested-by: Ross Brattain <ross.b.brattain@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/fcoe')
-rw-r--r--drivers/scsi/fcoe/fcoe.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 9f9600b67001..452b42169c48 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -356,10 +356,18 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
356 struct fcoe_interface *fcoe; 356 struct fcoe_interface *fcoe;
357 int err; 357 int err;
358 358
359 if (!try_module_get(THIS_MODULE)) {
360 FCOE_NETDEV_DBG(netdev,
361 "Could not get a reference to the module\n");
362 fcoe = ERR_PTR(-EBUSY);
363 goto out;
364 }
365
359 fcoe = kzalloc(sizeof(*fcoe), GFP_KERNEL); 366 fcoe = kzalloc(sizeof(*fcoe), GFP_KERNEL);
360 if (!fcoe) { 367 if (!fcoe) {
361 FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n"); 368 FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n");
362 return NULL; 369 fcoe = ERR_PTR(-ENOMEM);
370 goto out_nomod;
363 } 371 }
364 372
365 dev_hold(netdev); 373 dev_hold(netdev);
@@ -378,9 +386,15 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
378 fcoe_ctlr_destroy(&fcoe->ctlr); 386 fcoe_ctlr_destroy(&fcoe->ctlr);
379 kfree(fcoe); 387 kfree(fcoe);
380 dev_put(netdev); 388 dev_put(netdev);
381 return NULL; 389 fcoe = ERR_PTR(err);
390 goto out_nomod;
382 } 391 }
383 392
393 goto out;
394
395out_nomod:
396 module_put(THIS_MODULE);
397out:
384 return fcoe; 398 return fcoe;
385} 399}
386 400
@@ -442,6 +456,7 @@ static void fcoe_interface_release(struct kref *kref)
442 fcoe_ctlr_destroy(&fcoe->ctlr); 456 fcoe_ctlr_destroy(&fcoe->ctlr);
443 kfree(fcoe); 457 kfree(fcoe);
444 dev_put(netdev); 458 dev_put(netdev);
459 module_put(THIS_MODULE);
445} 460}
446 461
447/** 462/**
@@ -886,7 +901,6 @@ static void fcoe_if_destroy(struct fc_lport *lport)
886 901
887 /* Release the Scsi_Host */ 902 /* Release the Scsi_Host */
888 scsi_host_put(lport->host); 903 scsi_host_put(lport->host);
889 module_put(THIS_MODULE);
890} 904}
891 905
892/** 906/**
@@ -2135,15 +2149,10 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp)
2135 */ 2149 */
2136 if (THIS_MODULE->state != MODULE_STATE_LIVE) { 2150 if (THIS_MODULE->state != MODULE_STATE_LIVE) {
2137 rc = -ENODEV; 2151 rc = -ENODEV;
2138 goto out_nomod; 2152 goto out_nodev;
2139 } 2153 }
2140#endif 2154#endif
2141 2155
2142 if (!try_module_get(THIS_MODULE)) {
2143 rc = -EINVAL;
2144 goto out_nomod;
2145 }
2146
2147 netdev = fcoe_if_to_netdev(buffer); 2156 netdev = fcoe_if_to_netdev(buffer);
2148 if (!netdev) { 2157 if (!netdev) {
2149 rc = -ENODEV; 2158 rc = -ENODEV;
@@ -2157,8 +2166,8 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp)
2157 } 2166 }
2158 2167
2159 fcoe = fcoe_interface_create(netdev, fip_mode); 2168 fcoe = fcoe_interface_create(netdev, fip_mode);
2160 if (!fcoe) { 2169 if (IS_ERR(fcoe)) {
2161 rc = -ENOMEM; 2170 rc = PTR_ERR(fcoe);
2162 goto out_putdev; 2171 goto out_putdev;
2163 } 2172 }
2164 2173
@@ -2198,8 +2207,6 @@ out_free:
2198out_putdev: 2207out_putdev:
2199 dev_put(netdev); 2208 dev_put(netdev);
2200out_nodev: 2209out_nodev:
2201 module_put(THIS_MODULE);
2202out_nomod:
2203 rtnl_unlock(); 2210 rtnl_unlock();
2204 mutex_unlock(&fcoe_config_mutex); 2211 mutex_unlock(&fcoe_config_mutex);
2205 return rc; 2212 return rc;