diff options
author | Jens Axboe <axboe@kernel.dk> | 2018-11-07 14:34:05 -0700 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2018-11-07 14:34:05 -0700 |
commit | 6961cd4d0fde97f1cdb798ba21cf124ecfa0bf95 (patch) | |
tree | 4c7e07de3f4fc24b0e494e457232a996afb68435 /arch | |
parent | df376b2ed51a2777c3398e038992f62523c0f932 (diff) | |
download | linux-6961cd4d0fde97f1cdb798ba21cf124ecfa0bf95.tar.bz2 |
ubd: fix missing lock around request issue
We need to hold the device lock (and disable interrupts) while
writing new commands, or we could be interrupted while that
is happening and read invalid requests in the completion path.
Fixes: 4e6da0fe8058 ("um: Convert ubd driver to blk-mq")
Tested-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/um/drivers/ubd_kern.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 74c002ddc0ce..08831f5d83db 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1341,11 +1341,14 @@ static int ubd_queue_one_vec(struct blk_mq_hw_ctx *hctx, struct request *req, static blk_status_t ubd_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) { + struct ubd *ubd_dev = hctx->queue->queuedata; struct request *req = bd->rq; int ret = 0; blk_mq_start_request(req); + spin_lock_irq(&ubd_dev->lock); + if (req_op(req) == REQ_OP_FLUSH) { ret = ubd_queue_one_vec(hctx, req, 0, NULL); } else { @@ -1361,9 +1364,11 @@ static blk_status_t ubd_queue_rq(struct blk_mq_hw_ctx *hctx, } } out: - if (ret < 0) { + spin_unlock_irq(&ubd_dev->lock); + + if (ret < 0) blk_mq_requeue_request(req, true); - } + return BLK_STS_OK; } |