sd: don't grab a device references from driver methods
authorChristoph Hellwig <hch@lst.de>
Mon, 2 Feb 2015 13:01:25 +0000 (14:01 +0100)
committerJames Bottomley <JBottomley@Parallels.com>
Thu, 19 Mar 2015 13:40:53 +0000 (06:40 -0700)
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>
drivers/scsi/sd.c

index 6b78476d04bbf6983e43eba95d65fd7bb49082da..9e0c63e57affd837c37ebe0d4b4cbda60e7862f5 100644 (file)
@@ -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);
 }
 
 /**