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: Christoph Hellwig <hch@lst.de> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
e27829dc92
commit
3d9a1f530e
|
@ -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;
|
||||
|
||||
mutex_lock(&sd_ref_mutex);
|
||||
|
||||
if (disk->private_data) {
|
||||
sdkp = scsi_disk(disk);
|
||||
if (scsi_device_get(sdkp->device) == 0)
|
||||
|
@ -575,27 +577,6 @@ static struct scsi_disk *__scsi_disk_get(struct gendisk *disk)
|
|||
else
|
||||
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);
|
||||
return sdkp;
|
||||
}
|
||||
|
@ -610,8 +591,6 @@ static void scsi_disk_put(struct scsi_disk *sdkp)
|
|||
mutex_unlock(&sd_ref_mutex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd,
|
||||
unsigned int dix, unsigned int dif)
|
||||
{
|
||||
|
@ -1525,12 +1504,9 @@ static int sd_sync_cache(struct scsi_disk *sdkp)
|
|||
|
||||
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);
|
||||
scsi_disk_put(sdkp);
|
||||
}
|
||||
revalidate_disk(sdkp->disk);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3149,13 +3125,13 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
|
|||
*/
|
||||
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)
|
||||
return; /* this can happen */
|
||||
|
||||
if (pm_runtime_suspended(dev))
|
||||
goto exit;
|
||||
return;
|
||||
|
||||
if (sdkp->WCE && sdkp->media_present) {
|
||||
sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
|
||||
|
@ -3166,14 +3142,11 @@ static void sd_shutdown(struct device *dev)
|
|||
sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
|
||||
sd_start_stop_device(sdkp, 0);
|
||||
}
|
||||
|
||||
exit:
|
||||
scsi_disk_put(sdkp);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (!sdkp)
|
||||
|
@ -3199,7 +3172,6 @@ static int sd_suspend_common(struct device *dev, bool ignore_stop_errors)
|
|||
}
|
||||
|
||||
done:
|
||||
scsi_disk_put(sdkp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -3215,18 +3187,13 @@ static int sd_suspend_runtime(struct device *dev)
|
|||
|
||||
static int sd_resume(struct device *dev)
|
||||
{
|
||||
struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
|
||||
int ret = 0;
|
||||
struct scsi_disk *sdkp = dev_get_drvdata(dev);
|
||||
|
||||
if (!sdkp->device->manage_start_stop)
|
||||
goto done;
|
||||
return 0;
|
||||
|
||||
sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
|
||||
ret = sd_start_stop_device(sdkp, 1);
|
||||
|
||||
done:
|
||||
scsi_disk_put(sdkp);
|
||||
return ret;
|
||||
return sd_start_stop_device(sdkp, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue