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

Commit 71feb364 authored by Keith Busch's avatar Keith Busch Committed by Jens Axboe
Browse files

NVMe: Fix IO for extended metadata formats



This fixes io submit ioctl handling when using extended metadata
formats. When these formats are used, the user provides a single virtually
contiguous buffer containing both the block and metadata interleaved,
so the metadata size needs to be added to the total length and not mapped
as a separate transfer.

The command is also driver generated, so this patch does not enforce
blk-integrity extensions provide the metadata buffer.

Reported-by: default avatarMarcin Dziegielewski <marcin.dziegielewski@intel.com>
Signed-off-by: default avatarKeith Busch <keith.busch@intel.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent e112af0d
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -852,7 +852,8 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
	 * stripped/generated by the controller with PRACT=1.
	 */
	if (ns && ns->ms && !blk_integrity_rq(req)) {
		if (!(ns->pi_type && ns->ms == 8)) {
		if (!(ns->pi_type && ns->ms == 8) &&
					req->cmd_type != REQ_TYPE_DRV_PRIV) {
			req->errors = -EFAULT;
			blk_mq_complete_request(req);
			return BLK_MQ_RQ_QUEUE_OK;
@@ -1747,14 +1748,13 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
	meta_len = (io.nblocks + 1) * ns->ms;
	write = io.opcode & 1;

	if (meta_len) {
		if (((io.metadata & 3) || !io.metadata) && !ns->ext)
			return -EINVAL;

	if (ns->ext) {
		length += meta_len;
		meta_len = 0;
	}
	if (meta_len) {
		if (((io.metadata & 3) || !io.metadata) && !ns->ext)
			return -EINVAL;

		meta = dma_alloc_coherent(dev->dev, meta_len,
						&meta_dma, GFP_KERNEL);