aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2015-02-02 08:01:25 -0500
committerJames Bottomley <JBottomley@Parallels.com>2015-03-19 09:40:53 -0400
commit3d9a1f530e508ff6fc9ab8220016b02f1bce255b (patch)
treeafcdbfbdaea6b1a604dbc62f1f17d7da4fec7de5
parente27829dc92e549486b8248cdfa53e108abb6acfb (diff)
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>
-rw-r--r--drivers/scsi/sd.c55
1 files changed, 11 insertions, 44 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 6b78476d04bb..9e0c63e57aff 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -564,10 +564,12 @@ static int sd_major(int major_idx)
564 } 564 }
565} 565}
566 566
567static struct scsi_disk *__scsi_disk_get(struct gendisk *disk) 567static struct scsi_disk *scsi_disk_get(struct gendisk *disk)
568{ 568{
569 struct scsi_disk *sdkp = NULL; 569 struct scsi_disk *sdkp = NULL;
570 570
571 mutex_lock(&sd_ref_mutex);
572
571 if (disk->private_data) { 573 if (disk->private_data) {
572 sdkp = scsi_disk(disk); 574 sdkp = scsi_disk(disk);
573 if (scsi_device_get(sdkp->device) == 0) 575 if (scsi_device_get(sdkp->device) == 0)
@@ -575,27 +577,6 @@ static struct scsi_disk *__scsi_disk_get(struct gendisk *disk)
575 else 577 else
576 sdkp = NULL; 578 sdkp = NULL;
577 } 579 }
578 return sdkp;
579}
580
581static struct scsi_disk *scsi_disk_get(struct gendisk *disk)
582{
583 struct scsi_disk *sdkp;
584
585 mutex_lock(&sd_ref_mutex);
586 sdkp = __scsi_disk_get(disk);
587 mutex_unlock(&sd_ref_mutex);
588 return sdkp;
589}
590
591static struct scsi_disk *scsi_disk_get_from_dev(struct device *dev)
592{
593 struct scsi_disk *sdkp;
594
595 mutex_lock(&sd_ref_mutex);
596 sdkp = dev_get_drvdata(dev);
597 if (sdkp)
598 sdkp = __scsi_disk_get(sdkp->disk);
599 mutex_unlock(&sd_ref_mutex); 580 mutex_unlock(&sd_ref_mutex);
600 return sdkp; 581 return sdkp;
601} 582}
@@ -610,8 +591,6 @@ static void scsi_disk_put(struct scsi_disk *sdkp)
610 mutex_unlock(&sd_ref_mutex); 591 mutex_unlock(&sd_ref_mutex);
611} 592}
612 593
613
614
615static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd, 594static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd,
616 unsigned int dix, unsigned int dif) 595 unsigned int dix, unsigned int dif)
617{ 596{
@@ -1525,12 +1504,9 @@ static int sd_sync_cache(struct scsi_disk *sdkp)
1525 1504
1526static void sd_rescan(struct device *dev) 1505static void sd_rescan(struct device *dev)
1527{ 1506{
1528 struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); 1507 struct scsi_disk *sdkp = dev_get_drvdata(dev);
1529 1508
1530 if (sdkp) { 1509 revalidate_disk(sdkp->disk);
1531 revalidate_disk(sdkp->disk);
1532 scsi_disk_put(sdkp);
1533 }
1534} 1510}
1535 1511
1536 1512
@@ -3149,13 +3125,13 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
3149 */ 3125 */
3150static void sd_shutdown(struct device *dev) 3126static void sd_shutdown(struct device *dev)
3151{ 3127{
3152 struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); 3128 struct scsi_disk *sdkp = dev_get_drvdata(dev);
3153 3129
3154 if (!sdkp) 3130 if (!sdkp)
3155 return; /* this can happen */ 3131 return; /* this can happen */
3156 3132
3157 if (pm_runtime_suspended(dev)) 3133 if (pm_runtime_suspended(dev))
3158 goto exit; 3134 return;
3159 3135
3160 if (sdkp->WCE && sdkp->media_present) { 3136 if (sdkp->WCE && sdkp->media_present) {
3161 sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); 3137 sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
@@ -3166,14 +3142,11 @@ static void sd_shutdown(struct device *dev)
3166 sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); 3142 sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
3167 sd_start_stop_device(sdkp, 0); 3143 sd_start_stop_device(sdkp, 0);
3168 } 3144 }
3169
3170exit:
3171 scsi_disk_put(sdkp);
3172} 3145}
3173 3146
3174static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) 3147static int sd_suspend_common(struct device *dev, bool ignore_stop_errors)
3175{ 3148{
3176 struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); 3149 struct scsi_disk *sdkp = dev_get_drvdata(dev);
3177 int ret = 0; 3150 int ret = 0;
3178 3151
3179 if (!sdkp) 3152 if (!sdkp)
@@ -3199,7 +3172,6 @@ static int sd_suspend_common(struct device *dev, bool ignore_stop_errors)
3199 } 3172 }
3200 3173
3201done: 3174done:
3202 scsi_disk_put(sdkp);
3203 return ret; 3175 return ret;
3204} 3176}
3205 3177
@@ -3215,18 +3187,13 @@ static int sd_suspend_runtime(struct device *dev)
3215 3187
3216static int sd_resume(struct device *dev) 3188static int sd_resume(struct device *dev)
3217{ 3189{
3218 struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); 3190 struct scsi_disk *sdkp = dev_get_drvdata(dev);
3219 int ret = 0;
3220 3191
3221 if (!sdkp->device->manage_start_stop) 3192 if (!sdkp->device->manage_start_stop)
3222 goto done; 3193 return 0;
3223 3194
3224 sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); 3195 sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
3225 ret = sd_start_stop_device(sdkp, 1); 3196 return sd_start_stop_device(sdkp, 1);
3226
3227done:
3228 scsi_disk_put(sdkp);
3229 return ret;
3230} 3197}
3231 3198
3232/** 3199/**