diff options
author | Keith Busch <keith.busch@intel.com> | 2015-06-19 13:07:30 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2015-06-19 15:16:26 -0400 |
commit | 71feb364e7faadc681e714f7fdc2bede208ba26c (patch) | |
tree | f55db156d34c3b60cf2101c78d6f693efe67d6c7 /drivers/block | |
parent | e112af0dc9f55099b948e55077504a44b4162c79 (diff) |
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>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/nvme-core.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 12d5b7b03f9b..a501d3e6ac92 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c | |||
@@ -852,7 +852,8 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx, | |||
852 | * stripped/generated by the controller with PRACT=1. | 852 | * stripped/generated by the controller with PRACT=1. |
853 | */ | 853 | */ |
854 | if (ns && ns->ms && !blk_integrity_rq(req)) { | 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 | req->errors = -EFAULT; | 857 | req->errors = -EFAULT; |
857 | blk_mq_complete_request(req); | 858 | blk_mq_complete_request(req); |
858 | return BLK_MQ_RQ_QUEUE_OK; | 859 | return BLK_MQ_RQ_QUEUE_OK; |
@@ -1747,15 +1748,14 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) | |||
1747 | meta_len = (io.nblocks + 1) * ns->ms; | 1748 | meta_len = (io.nblocks + 1) * ns->ms; |
1748 | write = io.opcode & 1; | 1749 | write = io.opcode & 1; |
1749 | 1750 | ||
1751 | if (ns->ext) { | ||
1752 | length += meta_len; | ||
1753 | meta_len = 0; | ||
1754 | } | ||
1750 | if (meta_len) { | 1755 | if (meta_len) { |
1751 | if (((io.metadata & 3) || !io.metadata) && !ns->ext) | 1756 | if (((io.metadata & 3) || !io.metadata) && !ns->ext) |
1752 | return -EINVAL; | 1757 | return -EINVAL; |
1753 | 1758 | ||
1754 | if (ns->ext) { | ||
1755 | length += meta_len; | ||
1756 | meta_len = 0; | ||
1757 | } | ||
1758 | |||
1759 | meta = dma_alloc_coherent(dev->dev, meta_len, | 1759 | meta = dma_alloc_coherent(dev->dev, meta_len, |
1760 | &meta_dma, GFP_KERNEL); | 1760 | &meta_dma, GFP_KERNEL); |
1761 | if (!meta) { | 1761 | if (!meta) { |