diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 7d472c22c7d2079559d7b20e9830b71af8d9066c..fc1356d101b0a27de2a1240840336e723b5dcb45 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -544,6 +544,9 @@ EXPORT_SYMBOL(scsi_report_opcode); * Description: Gets a reference to the scsi_device and increments the use count * of the underlying LLDD module. You must hold host_lock of the * parent Scsi_Host or already have a reference when calling this. + * + * This will fail if a device is deleted or cancelled, or when the LLD module + * is in the process of being unloaded. */ int scsi_device_get(struct scsi_device *sdev) { @@ -551,12 +554,12 @@ int scsi_device_get(struct scsi_device *sdev) goto fail; if (!get_device(&sdev->sdev_gendev)) goto fail; - /* We can fail try_module_get if we're doing SCSI operations - * from module exit (like cache flush) - */ - __module_get(sdev->host->hostt->module); + if (!try_module_get(sdev->host->hostt->module)) + goto fail_put_device; return 0; +fail_put_device: + put_device(&sdev->sdev_gendev); fail: return -ENXIO; }