[PATCH for-next v11 10/13] nvme: wire up fixed buffer support for nvme passthrough
Anuj Gupta
anuj20.g at samsung.com
Thu Sep 29 05:06:29 PDT 2022
From: Kanchan Joshi <joshi.k at samsung.com>
if io_uring sends passthrough command with IORING_URING_CMD_FIXED flag,
use the pre-registered buffer for IO (non-vectored variant). Pass the
buffer/length to io_uring and get the bvec iterator for the range. Next,
pass this bvec to block-layer and obtain a bio/request for subsequent
processing.
Signed-off-by: Kanchan Joshi <joshi.k at samsung.com>
Suggested-by: Christoph Hellwig <hch at lst.de>
---
drivers/nvme/host/ioctl.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
index 4a7e45a263b6..25a68e8c60db 100644
--- a/drivers/nvme/host/ioctl.c
+++ b/drivers/nvme/host/ioctl.c
@@ -95,21 +95,31 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
void *meta = NULL;
int ret;
- if (!vec)
- ret = blk_rq_map_user(q, req, NULL, ubuffer, bufflen,
- GFP_KERNEL);
- else {
+ if (ioucmd && (ioucmd->flags & IORING_URING_CMD_FIXED)) {
+ struct iov_iter iter;
+
+ /* fixedbufs is only for non-vectored io */
+ if (WARN_ON_ONCE(vec))
+ return -EINVAL;
+ ret = io_uring_cmd_import_fixed(ubuffer, bufflen,
+ rq_data_dir(req), &iter, ioucmd);
+ if (ret < 0)
+ goto out;
+ ret = blk_rq_map_user_iov(q, req, NULL, &iter, GFP_KERNEL);
+ } else if (vec) {
struct iovec fast_iov[UIO_FASTIOV];
struct iovec *iov = fast_iov;
struct iov_iter iter;
- ret = import_iovec(rq_data_dir(req), ubuffer, bufflen,
- UIO_FASTIOV, &iov, &iter);
+ ret = import_iovec(rq_data_dir(req), nvme_to_user_ptr(ubuffer),
+ bufflen, UIO_FASTIOV, &iov, &iter);
if (ret < 0)
goto out;
-
ret = blk_rq_map_user_iov(q, req, NULL, &iter, GFP_KERNEL);
kfree(iov);
+ } else {
+ ret = blk_rq_map_user(q, req, NULL,
+ nvme_to_user_ptr(ubuffer), bufflen, GFP_KERNEL);
}
if (ret)
goto out;
--
2.25.1
More information about the Linux-nvme
mailing list