aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorKeith Busch <keith.busch@intel.com>2015-06-19 13:07:30 -0400
committerJens Axboe <axboe@fb.com>2015-06-19 15:16:26 -0400
commit71feb364e7faadc681e714f7fdc2bede208ba26c (patch)
treef55db156d34c3b60cf2101c78d6f693efe67d6c7 /drivers/block
parente112af0dc9f55099b948e55077504a44b4162c79 (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.c12
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) {