Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5261b85e authored by Rusty Russell's avatar Rusty Russell
Browse files

virtio_blk: don't crash, report error if virtqueue is broken.



A bad implementation of virtio might cause us to mark the virtqueue
broken: we'll dev_err() in that case, and the device is useless, but
let's not BUG_ON().

ENOMEM or ENOSPC implies the ring is full, and we should try again
later (-ENOMEM is documented to happen, but doesn't, as we fall
through to ENOSPC).

EIO means it's broken.

Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent a7c58146
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -158,6 +158,7 @@ static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req)
	unsigned long flags;
	unsigned int num;
	const bool last = (req->cmd_flags & REQ_END) != 0;
	int err;

	BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems);

@@ -198,11 +199,16 @@ static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req)
	}

	spin_lock_irqsave(&vblk->vq_lock, flags);
	if (__virtblk_add_req(vblk->vq, vbr, vbr->sg, num) < 0) {
	err = __virtblk_add_req(vblk->vq, vbr, vbr->sg, num);
	if (err) {
		virtqueue_kick(vblk->vq);
		spin_unlock_irqrestore(&vblk->vq_lock, flags);
		blk_mq_stop_hw_queue(hctx);
		/* Out of mem doesn't actually happen, since we fall back
		 * to direct descriptors */
		if (err == -ENOMEM || err == -ENOSPC)
			return BLK_MQ_RQ_QUEUE_BUSY;
		return BLK_MQ_RQ_QUEUE_ERROR;
	}

	if (last)