summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2018-11-08 00:34:05 +0300
committerJens Axboe <axboe@kernel.dk>2018-11-08 00:34:05 +0300
commit6961cd4d0fde97f1cdb798ba21cf124ecfa0bf95 (patch)
tree4c7e07de3f4fc24b0e494e457232a996afb68435
parentdf376b2ed51a2777c3398e038992f62523c0f932 (diff)
downloadlinux-6961cd4d0fde97f1cdb798ba21cf124ecfa0bf95.tar.xz
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>
-rw-r--r--arch/um/drivers/ubd_kern.c9
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;
}