Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3d9a1f53 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by James Bottomley
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent e27829dc
Loading
Loading
Loading
Loading
+11 −44
Original line number Diff line number Diff line
@@ -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);
	}
}


@@ -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);
}

/**