diff options
author | Christoph Hellwig <hch@lst.de> | 2015-02-02 08:01:25 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2015-03-19 09:40:53 -0400 |
commit | 3d9a1f530e508ff6fc9ab8220016b02f1bce255b (patch) | |
tree | afcdbfbdaea6b1a604dbc62f1f17d7da4fec7de5 | |
parent | e27829dc92e549486b8248cdfa53e108abb6acfb (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.c | 55 |
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 | ||
567 | static struct scsi_disk *__scsi_disk_get(struct gendisk *disk) | 567 | static 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 | |||
581 | static 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 | |||
591 | static 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 | |||
615 | static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd, | 594 | static 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 | ||
1526 | static void sd_rescan(struct device *dev) | 1505 | static 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 | */ |
3150 | static void sd_shutdown(struct device *dev) | 3126 | static 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 | |||
3170 | exit: | ||
3171 | scsi_disk_put(sdkp); | ||
3172 | } | 3145 | } |
3173 | 3146 | ||
3174 | static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) | 3147 | static 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 | ||
3201 | done: | 3174 | done: |
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 | ||
3216 | static int sd_resume(struct device *dev) | 3188 | static 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 | |||
3227 | done: | ||
3228 | scsi_disk_put(sdkp); | ||
3229 | return ret; | ||
3230 | } | 3197 | } |
3231 | 3198 | ||
3232 | /** | 3199 | /** |