summaryrefslogtreecommitdiff
path: root/drivers/scsi/sd.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-03-29 14:58:49 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-29 14:58:49 -0700
commit3467b90737e1551dbaa5b71fd5a54425fd4a72b2 (patch)
treed3a30a9b07d172740e8ce6268200d1954af42096 /drivers/scsi/sd.c
parent4ad528360cf6455bfaaf9164350ed74cbfadc7c5 (diff)
parentd6e2635b9cf7982102750c5d9e4ba1474afa0981 (diff)
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley: "Thirteen fixes, seven of which are for IBM fibre channel and three additional for fairly serious bugs in drivers (qla2xxx, mpt3sas, aacraid). Of the three core fixes, the most significant is probably the missed run queue causing an indefinite hang. The others are fixing a potential use after free on device close and silencing an incorrect warning" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: ibmvfc: Clean up transport events scsi: ibmvfc: Byte swap status and error codes when logging scsi: ibmvfc: Add failed PRLI to cmd_status lookup array scsi: ibmvfc: Remove "failed" from logged errors scsi: zfcp: reduce flood of fcrscn1 trace records on multi-element RSCN scsi: zfcp: fix scsi_eh host reset with port_forced ERP for non-NPIV FCP devices scsi: zfcp: fix rport unblock if deleted SCSI devices on Scsi_Host scsi: sd: Quiesce warning if device does not report optimal I/O size scsi: sd: Fix a race between closing an sd device and sd I/O scsi: core: Run queue when state is set to running after being blocked scsi: qla4xxx: fix a potential NULL pointer dereference scsi: aacraid: Insure we don't access PCIe space during AER/EEH scsi: mpt3sas: Fix kernel panic during expander reset
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r--drivers/scsi/sd.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 251db30d0882..2b2bc4b49d78 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1415,11 +1415,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);
}
@@ -3076,6 +3071,9 @@ static bool sd_validate_opt_xfer_size(struct scsi_disk *sdkp,
unsigned int opt_xfer_bytes =
logical_to_bytes(sdp, sdkp->opt_xfer_blocks);
+ if (sdkp->opt_xfer_blocks == 0)
+ return false;
+
if (sdkp->opt_xfer_blocks > dev_max) {
sd_first_printk(KERN_WARNING, sdkp,
"Optimal transfer size %u logical blocks " \
@@ -3505,9 +3503,21 @@ 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;
+
ida_free(&sd_index_ida, sdkp->index);
+ /*
+ * 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);