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 <h...@lst.de>
---
 drivers/scsi/sd.c | 55 +++++++++++--------------------------------------------
 1 file changed, 11 insertions(+), 44 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 3995169..1f06274 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -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);
 }
 
 
@@ -3147,13 +3123,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");
@@ -3164,14 +3140,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)
@@ -3197,7 +3170,6 @@ static int sd_suspend_common(struct device *dev, bool 
ignore_stop_errors)
        }
 
 done:
-       scsi_disk_put(sdkp);
        return ret;
 }
 
@@ -3213,18 +3185,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);
 }
 
 /**
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to