Commit d512a35f authored by James Bottomley's avatar James Bottomley Committed by James Bottomley

[PATCH] fix LLD module refcounting in sr.c

The patch to close all the open/close/hotplug races in sr left the
module refcounting broken so that the ULD housing the CD device now
can't be removed until the device itself is removed.

This patch (structurally identical to the one for sd.c to perform the
same function) fixes the module refcounting.
parent da2a5d68
...@@ -138,7 +138,15 @@ static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk) ...@@ -138,7 +138,15 @@ static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk)
goto out; goto out;
cd = scsi_cd(disk); cd = scsi_cd(disk);
if (!kref_get(&cd->kref)) if (!kref_get(&cd->kref))
cd = NULL; goto out_null;
if (scsi_device_get(cd->device))
goto out_put;
goto out;
out_put:
kref_put(&cd->kref);
out_null:
cd = NULL;
out: out:
up(&sr_ref_sem); up(&sr_ref_sem);
return cd; return cd;
...@@ -147,6 +155,7 @@ static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk) ...@@ -147,6 +155,7 @@ static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk)
static inline void scsi_cd_put(struct scsi_cd *cd) static inline void scsi_cd_put(struct scsi_cd *cd)
{ {
down(&sr_ref_sem); down(&sr_ref_sem);
scsi_device_put(cd->device);
kref_put(&cd->kref); kref_put(&cd->kref);
up(&sr_ref_sem); up(&sr_ref_sem);
} }
...@@ -558,13 +567,10 @@ static int sr_probe(struct device *dev) ...@@ -558,13 +567,10 @@ static int sr_probe(struct device *dev)
if (sdev->type != TYPE_ROM && sdev->type != TYPE_WORM) if (sdev->type != TYPE_ROM && sdev->type != TYPE_WORM)
goto fail; goto fail;
if ((error = scsi_device_get(sdev)) != 0)
goto fail;
error = -ENOMEM; error = -ENOMEM;
cd = kmalloc(sizeof(*cd), GFP_KERNEL); cd = kmalloc(sizeof(*cd), GFP_KERNEL);
if (!cd) if (!cd)
goto fail_put_sdev; goto fail;
memset(cd, 0, sizeof(*cd)); memset(cd, 0, sizeof(*cd));
kref_init(&cd->kref, sr_kref_release); kref_init(&cd->kref, sr_kref_release);
...@@ -637,8 +643,6 @@ static int sr_probe(struct device *dev) ...@@ -637,8 +643,6 @@ static int sr_probe(struct device *dev)
put_disk(disk); put_disk(disk);
fail_free: fail_free:
kfree(cd); kfree(cd);
fail_put_sdev:
scsi_device_put(sdev);
fail: fail:
return error; return error;
} }
...@@ -926,7 +930,6 @@ static int sr_packet(struct cdrom_device_info *cdi, ...@@ -926,7 +930,6 @@ static int sr_packet(struct cdrom_device_info *cdi,
static void sr_kref_release(struct kref *kref) static void sr_kref_release(struct kref *kref)
{ {
struct scsi_cd *cd = container_of(kref, struct scsi_cd, kref); struct scsi_cd *cd = container_of(kref, struct scsi_cd, kref);
struct scsi_device *sdev = cd->device;
struct gendisk *disk = cd->disk; struct gendisk *disk = cd->disk;
spin_lock(&sr_index_lock); spin_lock(&sr_index_lock);
...@@ -940,8 +943,6 @@ static void sr_kref_release(struct kref *kref) ...@@ -940,8 +943,6 @@ static void sr_kref_release(struct kref *kref)
put_disk(disk); put_disk(disk);
kfree(cd); kfree(cd);
scsi_device_put(sdev);
} }
static int sr_remove(struct device *dev) static int sr_remove(struct device *dev)
...@@ -950,7 +951,9 @@ static int sr_remove(struct device *dev) ...@@ -950,7 +951,9 @@ static int sr_remove(struct device *dev)
del_gendisk(cd->disk); del_gendisk(cd->disk);
scsi_cd_put(cd); down(&sr_ref_sem);
kref_put(&cd->kref);
up(&sr_ref_sem);
return 0; return 0;
} }
......
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