Commit 3d9a1f53 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by James Bottomley

sd: don't grab a device references from driver methods

The device model already takes care of races between ->remove and
->shutdown vs its other methods, and we now take care about locking
them out for ->rescan as well.

This is a partial revert of commit 39b7f1 ("[SCSI] sd: Fix refcounting").
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent e27829dc
...@@ -564,10 +564,12 @@ static int sd_major(int major_idx) ...@@ -564,10 +564,12 @@ static int sd_major(int major_idx)
} }
} }
static struct scsi_disk *__scsi_disk_get(struct gendisk *disk) static struct scsi_disk *scsi_disk_get(struct gendisk *disk)
{ {
struct scsi_disk *sdkp = NULL; struct scsi_disk *sdkp = NULL;
mutex_lock(&sd_ref_mutex);
if (disk->private_data) { if (disk->private_data) {
sdkp = scsi_disk(disk); sdkp = scsi_disk(disk);
if (scsi_device_get(sdkp->device) == 0) if (scsi_device_get(sdkp->device) == 0)
...@@ -575,27 +577,6 @@ static struct scsi_disk *__scsi_disk_get(struct gendisk *disk) ...@@ -575,27 +577,6 @@ static struct scsi_disk *__scsi_disk_get(struct gendisk *disk)
else else
sdkp = NULL; sdkp = NULL;
} }
return sdkp;
}
static struct scsi_disk *scsi_disk_get(struct gendisk *disk)
{
struct scsi_disk *sdkp;
mutex_lock(&sd_ref_mutex);
sdkp = __scsi_disk_get(disk);
mutex_unlock(&sd_ref_mutex);
return sdkp;
}
static struct scsi_disk *scsi_disk_get_from_dev(struct device *dev)
{
struct scsi_disk *sdkp;
mutex_lock(&sd_ref_mutex);
sdkp = dev_get_drvdata(dev);
if (sdkp)
sdkp = __scsi_disk_get(sdkp->disk);
mutex_unlock(&sd_ref_mutex); mutex_unlock(&sd_ref_mutex);
return sdkp; return sdkp;
} }
...@@ -610,8 +591,6 @@ static void scsi_disk_put(struct scsi_disk *sdkp) ...@@ -610,8 +591,6 @@ static void scsi_disk_put(struct scsi_disk *sdkp)
mutex_unlock(&sd_ref_mutex); mutex_unlock(&sd_ref_mutex);
} }
static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd, static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd,
unsigned int dix, unsigned int dif) unsigned int dix, unsigned int dif)
{ {
...@@ -1525,12 +1504,9 @@ static int sd_sync_cache(struct scsi_disk *sdkp) ...@@ -1525,12 +1504,9 @@ static int sd_sync_cache(struct scsi_disk *sdkp)
static void sd_rescan(struct device *dev) static void sd_rescan(struct device *dev)
{ {
struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); struct scsi_disk *sdkp = dev_get_drvdata(dev);
if (sdkp) { revalidate_disk(sdkp->disk);
revalidate_disk(sdkp->disk);
scsi_disk_put(sdkp);
}
} }
...@@ -3149,13 +3125,13 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start) ...@@ -3149,13 +3125,13 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
*/ */
static void sd_shutdown(struct device *dev) static void sd_shutdown(struct device *dev)
{ {
struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); struct scsi_disk *sdkp = dev_get_drvdata(dev);
if (!sdkp) if (!sdkp)
return; /* this can happen */ return; /* this can happen */
if (pm_runtime_suspended(dev)) if (pm_runtime_suspended(dev))
goto exit; return;
if (sdkp->WCE && sdkp->media_present) { if (sdkp->WCE && sdkp->media_present) {
sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
...@@ -3166,14 +3142,11 @@ static void sd_shutdown(struct device *dev) ...@@ -3166,14 +3142,11 @@ static void sd_shutdown(struct device *dev)
sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
sd_start_stop_device(sdkp, 0); sd_start_stop_device(sdkp, 0);
} }
exit:
scsi_disk_put(sdkp);
} }
static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) static int sd_suspend_common(struct device *dev, bool ignore_stop_errors)
{ {
struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); struct scsi_disk *sdkp = dev_get_drvdata(dev);
int ret = 0; int ret = 0;
if (!sdkp) if (!sdkp)
...@@ -3199,7 +3172,6 @@ static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) ...@@ -3199,7 +3172,6 @@ static int sd_suspend_common(struct device *dev, bool ignore_stop_errors)
} }
done: done:
scsi_disk_put(sdkp);
return ret; return ret;
} }
...@@ -3215,18 +3187,13 @@ static int sd_suspend_runtime(struct device *dev) ...@@ -3215,18 +3187,13 @@ static int sd_suspend_runtime(struct device *dev)
static int sd_resume(struct device *dev) static int sd_resume(struct device *dev)
{ {
struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); struct scsi_disk *sdkp = dev_get_drvdata(dev);
int ret = 0;
if (!sdkp->device->manage_start_stop) if (!sdkp->device->manage_start_stop)
goto done; return 0;
sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
ret = sd_start_stop_device(sdkp, 1); return sd_start_stop_device(sdkp, 1);
done:
scsi_disk_put(sdkp);
return ret;
} }
/** /**
......
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