Commit fe58b80a authored by Mike Anderson's avatar Mike Anderson Committed by James Bottomley

[PATCH] fix module unload problem in sd

Move scsi_device_get out of sd probe path to allow module to be unloaded
when devices are not open.
parent d7e2a19f
...@@ -179,6 +179,15 @@ static struct scsi_disk *scsi_disk_get(struct gendisk *disk) ...@@ -179,6 +179,15 @@ static struct scsi_disk *scsi_disk_get(struct gendisk *disk)
goto out; goto out;
sdkp = scsi_disk(disk); sdkp = scsi_disk(disk);
if (!kref_get(&sdkp->kref)) if (!kref_get(&sdkp->kref))
goto out_sdkp;
if (scsi_device_get(sdkp->device))
goto out_put;
up(&sd_ref_sem);
return sdkp;
out_put:
kref_put(&sdkp->kref);
out_sdkp:
sdkp = NULL; sdkp = NULL;
out: out:
up(&sd_ref_sem); up(&sd_ref_sem);
...@@ -188,6 +197,7 @@ static struct scsi_disk *scsi_disk_get(struct gendisk *disk) ...@@ -188,6 +197,7 @@ static struct scsi_disk *scsi_disk_get(struct gendisk *disk)
static void scsi_disk_put(struct scsi_disk *sdkp) static void scsi_disk_put(struct scsi_disk *sdkp)
{ {
down(&sd_ref_sem); down(&sd_ref_sem);
scsi_device_put(sdkp->device);
kref_put(&sdkp->kref); kref_put(&sdkp->kref);
up(&sd_ref_sem); up(&sd_ref_sem);
} }
...@@ -1342,16 +1352,13 @@ static int sd_probe(struct device *dev) ...@@ -1342,16 +1352,13 @@ static int sd_probe(struct device *dev)
if ((sdp->type != TYPE_DISK) && (sdp->type != TYPE_MOD)) if ((sdp->type != TYPE_DISK) && (sdp->type != TYPE_MOD))
goto out; goto out;
if ((error = scsi_device_get(sdp)) != 0)
goto out;
SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n", SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n",
sdp->host->host_no, sdp->channel, sdp->id, sdp->lun)); sdp->host->host_no, sdp->channel, sdp->id, sdp->lun));
error = -ENOMEM; error = -ENOMEM;
sdkp = kmalloc(sizeof(*sdkp), GFP_KERNEL); sdkp = kmalloc(sizeof(*sdkp), GFP_KERNEL);
if (!sdkp) if (!sdkp)
goto out_put_sdev; goto out;
memset (sdkp, 0, sizeof(*sdkp)); memset (sdkp, 0, sizeof(*sdkp));
kref_init(&sdkp->kref, scsi_disk_release); kref_init(&sdkp->kref, scsi_disk_release);
...@@ -1427,8 +1434,6 @@ static int sd_probe(struct device *dev) ...@@ -1427,8 +1434,6 @@ static int sd_probe(struct device *dev)
put_disk(gd); put_disk(gd);
out_free: out_free:
kfree(sdkp); kfree(sdkp);
out_put_sdev:
scsi_device_put(sdp);
out: out:
return error; return error;
} }
...@@ -1450,7 +1455,9 @@ static int sd_remove(struct device *dev) ...@@ -1450,7 +1455,9 @@ static int sd_remove(struct device *dev)
del_gendisk(sdkp->disk); del_gendisk(sdkp->disk);
sd_shutdown(dev); sd_shutdown(dev);
scsi_disk_put(sdkp); down(&sd_ref_sem);
kref_put(&sdkp->kref);
up(&sd_ref_sem);
return 0; return 0;
} }
...@@ -1479,8 +1486,6 @@ static void scsi_disk_release(struct kref *kref) ...@@ -1479,8 +1486,6 @@ static void scsi_disk_release(struct kref *kref)
put_disk(disk); put_disk(disk);
kfree(sdkp); kfree(sdkp);
scsi_device_put(sdev);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment