summaryrefslogtreecommitdiff
path: root/io_uring
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2024-10-16 15:48:38 -0600
committerJens Axboe <axboe@kernel.dk>2024-10-29 13:43:27 -0600
commit892d3e80e1b9fc09aefdfd4d31f10f3d018863a0 (patch)
tree9f1b4453832d3ce96d6f976884dd5bbea88831a7 /io_uring
parentc919790060230ac2b1824bbf4d3b64eb51f471ff (diff)
downloadlwn-892d3e80e1b9fc09aefdfd4d31f10f3d018863a0.tar.gz
lwn-892d3e80e1b9fc09aefdfd4d31f10f3d018863a0.zip
io_uring/uring_cmd: get rid of using req->imu
It's pretty pointless to use io_kiocb as intermediate storage for this, so split the validity check and the actual usage. The resource node is assigned upfront at prep time, to prevent it from going away. The actual import is never called with the ctx->uring_lock held, so grab it for the import. Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'io_uring')
-rw-r--r--io_uring/uring_cmd.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/io_uring/uring_cmd.c b/io_uring/uring_cmd.c
index 39c3c816ec78..58d0b817d6ea 100644
--- a/io_uring/uring_cmd.c
+++ b/io_uring/uring_cmd.c
@@ -211,11 +211,15 @@ int io_uring_cmd_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
struct io_ring_ctx *ctx = req->ctx;
u16 index;
- req->buf_index = READ_ONCE(sqe->buf_index);
- if (unlikely(req->buf_index >= ctx->nr_user_bufs))
+ index = READ_ONCE(sqe->buf_index);
+ if (unlikely(index >= ctx->nr_user_bufs))
return -EFAULT;
- index = array_index_nospec(req->buf_index, ctx->nr_user_bufs);
- req->imu = ctx->user_bufs[index];
+ req->buf_index = array_index_nospec(index, ctx->nr_user_bufs);
+ /*
+ * Pi node upfront, prior to io_uring_cmd_import_fixed()
+ * being called. This prevents destruction of the mapped buffer
+ * we'll need at actual import time.
+ */
io_req_set_rsrc_node(req, ctx, 0);
}
ioucmd->cmd_op = READ_ONCE(sqe->cmd_op);
@@ -272,8 +276,17 @@ int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw,
struct iov_iter *iter, void *ioucmd)
{
struct io_kiocb *req = cmd_to_io_kiocb(ioucmd);
+ struct io_ring_ctx *ctx = req->ctx;
+
+ /* Must have had rsrc_node assigned at prep time */
+ if (req->rsrc_node) {
+ struct io_mapped_ubuf *imu;
+
+ imu = READ_ONCE(ctx->user_bufs[req->buf_index]);
+ return io_import_fixed(rw, iter, imu, ubuf, len);
+ }
- return io_import_fixed(rw, iter, req->imu, ubuf, len);
+ return -EFAULT;
}
EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed);