From: Caleb Sander Mateos <csander@purestorage.com>
To: Jens Axboe <axboe@kernel.dk>, Keith Busch <kbusch@kernel.org>,
Christoph Hellwig <hch@lst.de>, Sagi Grimberg <sagi@grimberg.me>
Cc: io-uring@vger.kernel.org, linux-nvme@lists.infradead.org,
linux-block@vger.kernel.org, linux-kernel@vger.kernel.org,
Caleb Sander Mateos <csander@purestorage.com>
Subject: [PATCH 4/6] nvme/ioctl: pass iov_iter to nvme_map_user_request()
Date: Wed, 9 Sep 2026 16:28:34 -0600 [thread overview]
Message-ID: <20260909222836.2475352-5-csander@purestorage.com> (raw)
In-Reply-To: <20260909222836.2475352-1-csander@purestorage.com>
To allow nvme_map_user_request() to accept an io_uring registered buffer
(represented as a ITER_BVEC iov_iter) for the metadata buffer, pass it
as an iov_iter argument. Move the conversions from user address-length
pairs into iov_iters to the callers. A NULL iov_iter pointer represents
no metadata buffer.
Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
---
drivers/nvme/host/ioctl.c | 46 +++++++++++++++++++++++----------------
1 file changed, 27 insertions(+), 19 deletions(-)
diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
index e69c49c334a0..8e722184ecf1 100644
--- a/drivers/nvme/host/ioctl.c
+++ b/drivers/nvme/host/ioctl.c
@@ -152,21 +152,20 @@ static struct request *nvme_alloc_user_request(struct request_queue *q,
nvme_req(req)->flags |= NVME_REQ_USERCMD;
return req;
}
static int nvme_map_user_request(struct request *req, u64 ubuffer,
- unsigned bufflen, void __user *meta_buffer, unsigned meta_len,
- struct iov_iter *iter, unsigned int flags)
+ unsigned bufflen, struct iov_iter *iter,
+ struct iov_iter *meta_iter, unsigned int flags)
{
struct request_queue *q = req->q;
struct nvme_ns *ns = q->queuedata;
struct block_device *bdev = ns ? ns->disk->part0 : NULL;
bool supports_metadata = bdev && blk_get_integrity(bdev->bd_disk);
- bool has_metadata = meta_buffer && meta_len;
int ret;
- if (has_metadata && !supports_metadata)
+ if (meta_iter && !supports_metadata)
return -EINVAL;
if (iter)
ret = blk_rq_map_user_iov(q, req, NULL, iter, GFP_KERNEL);
else
@@ -174,16 +173,12 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
bufflen, GFP_KERNEL, flags & NVME_IOCTL_VEC, 0,
0, rq_data_dir(req));
if (ret)
return ret;
- if (has_metadata) {
- struct iov_iter meta_iter;
-
- iov_iter_ubuf(&meta_iter, rq_data_dir(req), meta_buffer,
- meta_len);
- ret = blk_rq_integrity_map_user(req, &meta_iter);
+ if (meta_iter) {
+ ret = blk_rq_integrity_map_user(req, meta_iter);
if (ret)
goto out_unmap;
}
return ret;
@@ -210,12 +205,20 @@ static int nvme_submit_user_cmd(struct request_queue *q,
if (IS_ERR(req))
return PTR_ERR(req);
req->timeout = timeout;
if (ubuffer && bufflen) {
- ret = nvme_map_user_request(req, ubuffer, bufflen, meta_buffer,
- meta_len, NULL, flags);
+ struct iov_iter meta_iter;
+ struct iov_iter *map_meta_iter = NULL;
+
+ if (meta_buffer && meta_len) {
+ iov_iter_ubuf(&meta_iter, rq_data_dir(req), meta_buffer,
+ meta_len);
+ map_meta_iter = &meta_iter;
+ }
+ ret = nvme_map_user_request(req, ubuffer, bufflen, NULL,
+ map_meta_iter, flags);
if (ret)
goto out_free_req;
}
bio = req->bio;
@@ -480,18 +483,19 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
const struct nvme_uring_cmd *cmd = io_uring_sqe128_cmd(ioucmd->sqe,
struct nvme_uring_cmd);
struct request_queue *q = ns ? ns->queue : ctrl->admin_q;
bool open_for_write = ioucmd->file->f_mode & FMODE_WRITE;
struct nvme_command c;
- struct iov_iter iter;
- struct iov_iter *map_iter = NULL;
+ struct iov_iter iter, meta_iter;
+ struct iov_iter *map_iter = NULL, *map_meta_iter = NULL;
struct request *req;
blk_opf_t rq_flags = 0;
blk_mq_req_flags_t blk_flags = 0;
u32 metadata_len, data_len;
u64 metadata, addr;
u32 timeout_ms;
+ int ddir;
int ret;
c.common.opcode = READ_ONCE(cmd->opcode);
c.common.flags = READ_ONCE(cmd->flags);
if (c.common.flags)
@@ -520,13 +524,12 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
addr = READ_ONCE(cmd->addr);
data_len = READ_ONCE(cmd->data_len);
metadata_len = READ_ONCE(cmd->metadata_len);
timeout_ms = READ_ONCE(cmd->timeout_ms);
+ ddir = nvme_is_write(&c) ? WRITE : READ;
if (data_len && (ioucmd->flags & IORING_URING_CMD_FIXED)) {
- int ddir = nvme_is_write(&c) ? WRITE : READ;
-
if (vec)
ret = io_uring_cmd_import_fixed_vec(ioucmd,
u64_to_user_ptr(addr), data_len,
ddir, &iter, issue_flags);
else
@@ -535,10 +538,15 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
if (ret < 0)
return ret;
map_iter = &iter;
}
+ if (data_len && metadata && metadata_len) {
+ iov_iter_ubuf(&meta_iter, ddir, nvme_to_user_ptr(metadata),
+ metadata_len);
+ map_meta_iter = &meta_iter;
+ }
if (issue_flags & IO_URING_F_NONBLOCK) {
rq_flags |= REQ_NOWAIT;
blk_flags = BLK_MQ_REQ_NOWAIT;
}
@@ -549,13 +557,13 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
if (IS_ERR(req))
return PTR_ERR(req);
req->timeout = timeout_ms ? msecs_to_jiffies(timeout_ms) : 0;
if (data_len) {
- ret = nvme_map_user_request(req, addr, data_len,
- nvme_to_user_ptr(metadata), metadata_len,
- map_iter, vec ? NVME_IOCTL_VEC : 0);
+ ret = nvme_map_user_request(req, addr, data_len, map_iter,
+ map_meta_iter,
+ vec ? NVME_IOCTL_VEC : 0);
if (ret)
goto out_free_req;
}
/* to free bio on completion, as req->bio will be null at that time */
--
2.55.0
next prev parent reply other threads:[~2026-09-09 22:29 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-09 22:28 [PATCH 0/6] io_uring/nvme: support fixed buffer for metadata Caleb Sander Mateos
2026-09-09 22:28 ` [PATCH 1/6] bio-integrity: remove dead bio_integrity_copy_user() error path Caleb Sander Mateos
2026-09-09 22:28 ` [PATCH 2/6] nvme/ioctl: remove struct nvme_uring_data Caleb Sander Mateos
2026-09-09 22:28 ` [PATCH 3/6] blk-integrity: pass iov_iter to blk_rq_integrity_map_user() Caleb Sander Mateos
2026-09-09 22:28 ` Caleb Sander Mateos [this message]
2026-09-09 22:28 ` [PATCH 5/6] io_uring/cmd: support fixed buffer for metadata Caleb Sander Mateos
2026-09-09 22:28 ` [PATCH 6/6] nvme/ioctl: " Caleb Sander Mateos
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260909222836.2475352-5-csander@purestorage.com \
--to=csander@purestorage.com \
--cc=axboe@kernel.dk \
--cc=hch@lst.de \
--cc=io-uring@vger.kernel.org \
--cc=kbusch@kernel.org \
--cc=linux-block@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=sagi@grimberg.me \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.