Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Marcin Dziegielewski <marcin.dziegielewski@intel.com>
Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Jens Axboe <axboe@fb.com>

authored by

Keith Busch and committed by
Jens Axboe
71feb364 e112af0d

+6 -6
+6 -6
drivers/block/nvme-core.c
··· 852 852 * stripped/generated by the controller with PRACT=1. 853 853 */ 854 854 if (ns && ns->ms && !blk_integrity_rq(req)) { 855 - if (!(ns->pi_type && ns->ms == 8)) { 855 + if (!(ns->pi_type && ns->ms == 8) && 856 + req->cmd_type != REQ_TYPE_DRV_PRIV) { 856 857 req->errors = -EFAULT; 857 858 blk_mq_complete_request(req); 858 859 return BLK_MQ_RQ_QUEUE_OK; ··· 1748 1747 meta_len = (io.nblocks + 1) * ns->ms; 1749 1748 write = io.opcode & 1; 1750 1749 1750 + if (ns->ext) { 1751 + length += meta_len; 1752 + meta_len = 0; 1753 + } 1751 1754 if (meta_len) { 1752 1755 if (((io.metadata & 3) || !io.metadata) && !ns->ext) 1753 1756 return -EINVAL; 1754 - 1755 - if (ns->ext) { 1756 - length += meta_len; 1757 - meta_len = 0; 1758 - } 1759 1757 1760 1758 meta = dma_alloc_coherent(dev->dev, meta_len, 1761 1759 &meta_dma, GFP_KERNEL);