Home Home > GIT Browse > SLE15-AZURE
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLee Duncan <lduncan@suse.com>2019-09-06 10:51:48 -0700
committerLee Duncan <lduncan@suse.com>2019-09-06 10:51:48 -0700
commit19c8ab772e056034e80f63bb7a8abad7f12599ed (patch)
treea82a626338814b3c17ec66fa6d5d1cb3348bc5f8
parent001d5e2bfe425310c7642be653db82163f63634e (diff)
scsi: sd: Fix a race between closing an sd device and sd I/O
(git-fixes). suse-commit: 8f5e62ed6e89ffb5f98352ca481684abd1263599
-rw-r--r--drivers/scsi/sd.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 5a7d108fe712..88f8ea86b5a2 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1439,11 +1439,6 @@ static void sd_release(struct gendisk *disk, fmode_t mode)
scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
}
- /*
- * XXX and what if there are packets in flight and this close()
- * XXX is followed by a "rmmod sd_mod"?
- */
-
scsi_disk_put(sdkp);
}
@@ -3559,11 +3554,23 @@ static void scsi_disk_release(struct device *dev)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
struct gendisk *disk = sdkp->disk;
+ struct request_queue *q = disk->queue;
spin_lock(&sd_index_lock);
ida_remove(&sd_index_ida, sdkp->index);
spin_unlock(&sd_index_lock);
+ /*
+ * Wait until all requests that are in progress have completed.
+ * This is necessary to avoid that e.g. scsi_end_request() crashes
+ * due to clearing the disk->private_data pointer. Wait from inside
+ * scsi_disk_release() instead of from sd_release() to avoid that
+ * freezing and unfreezing the request queue affects user space I/O
+ * in case multiple processes open a /dev/sd... node concurrently.
+ */
+ blk_mq_freeze_queue(q);
+ blk_mq_unfreeze_queue(q);
+
disk->private_data = NULL;
put_disk(disk);
put_device(&sdkp->device->sdev_gendev);