summaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-11-16 09:31:59 -0600
committerLinus Torvalds <torvalds@linux-foundation.org>2018-11-16 09:31:59 -0600
commit59749c2d49bf28df69ac4bcabf1f69b00d3dca59 (patch)
treeb255e9caf4e731edfb671368d38b72d7e0d9af84 /drivers/scsi
parent9b5f361ac4a923bf53ca8c0875509ef68c8958cd (diff)
parent8dc765d438f1e42b3e8227b3b09fad7d73f4ec9a (diff)
downloadlinux-59749c2d49bf28df69ac4bcabf1f69b00d3dca59.tar.bz2
Merge tag 'for-linus-20181115' of git://git.kernel.dk/linux-block
Pull block fixes from Jens Axboe: - Discard loop fix, caused by integer overflow (Dave) - Blacklist of Samsung drive that hangs with power management (Diego) - Copy bio priority when cloning it (Hannes) - Fix race condition exposed in floppy (me) - Fix SCSI queue cleanup regression. While elusive, it caused oopses in queue running (Ming) - Fix bad string copy in kyber tracing (Omar) * tag 'for-linus-20181115' of git://git.kernel.dk/linux-block: SCSI: fix queue cleanup race before queue initialization is done block: fix 32 bit overflow in __blkdev_issue_discard() libata: blacklist SAMSUNG MZ7TD256HAFV-000L9 SSD block: copy ioprio in __bio_clone_fast() and bounce kyber: fix wrong strlcpy() size in trace_kyber_latency() floppy: fix race condition in __floppy_read_block_0()
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/scsi_lib.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index c7fccbb8f554..fa6e0c3b3aa6 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -697,6 +697,12 @@ static bool scsi_end_request(struct request *req, blk_status_t error,
*/
scsi_mq_uninit_cmd(cmd);
+ /*
+ * queue is still alive, so grab the ref for preventing it
+ * from being cleaned up during running queue.
+ */
+ percpu_ref_get(&q->q_usage_counter);
+
__blk_mq_end_request(req, error);
if (scsi_target(sdev)->single_lun ||
@@ -704,6 +710,8 @@ static bool scsi_end_request(struct request *req, blk_status_t error,
kblockd_schedule_work(&sdev->requeue_work);
else
blk_mq_run_hw_queues(q, true);
+
+ percpu_ref_put(&q->q_usage_counter);
} else {
unsigned long flags;