Add an API for fetching the registered buffer associated with a io_uring cmd. This is useful for callers who need access to the buffer but do not have prior knowledge of the buffer's user address or length. Signed-off-by: Joanne Koong --- include/linux/io_uring/cmd.h | 3 +++ io_uring/rsrc.c | 14 ++++++++++++++ io_uring/rsrc.h | 2 ++ io_uring/uring_cmd.c | 13 +++++++++++++ 4 files changed, 32 insertions(+) diff --git a/include/linux/io_uring/cmd.h b/include/linux/io_uring/cmd.h index 7509025b4071..8c11d9a92733 100644 --- a/include/linux/io_uring/cmd.h +++ b/include/linux/io_uring/cmd.h @@ -43,6 +43,9 @@ int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, struct iov_iter *iter, struct io_uring_cmd *ioucmd, unsigned int issue_flags); +int io_uring_cmd_import_fixed_full(int rw, struct iov_iter *iter, + struct io_uring_cmd *ioucmd, + unsigned int issue_flags); int io_uring_cmd_import_fixed_vec(struct io_uring_cmd *ioucmd, const struct iovec __user *uvec, size_t uvec_segs, diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index d787c16dc1c3..2c3d8489ae52 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -1147,6 +1147,20 @@ int io_import_reg_buf(struct io_kiocb *req, struct iov_iter *iter, return io_import_fixed(ddir, iter, node->buf, buf_addr, len); } +int io_import_reg_buf_full(struct io_kiocb *req, struct iov_iter *iter, + int ddir, unsigned issue_flags) +{ + struct io_rsrc_node *node; + struct io_mapped_ubuf *imu; + + node = io_find_buf_node(req, issue_flags); + if (!node) + return -EFAULT; + + imu = node->buf; + return io_import_fixed(ddir, iter, imu, imu->ubuf, imu->len); +} + /* Lock two rings at once. The rings must be different! */ static void lock_two_rings(struct io_ring_ctx *ctx1, struct io_ring_ctx *ctx2) { diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h index a3ca6ba66596..4e01eb0f277e 100644 --- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -64,6 +64,8 @@ struct io_rsrc_node *io_find_buf_node(struct io_kiocb *req, int io_import_reg_buf(struct io_kiocb *req, struct iov_iter *iter, u64 buf_addr, size_t len, int ddir, unsigned issue_flags); +int io_import_reg_buf_full(struct io_kiocb *req, struct iov_iter *iter, + int ddir, unsigned issue_flags); int io_import_reg_vec(int ddir, struct iov_iter *iter, struct io_kiocb *req, struct iou_vec *vec, unsigned nr_iovs, unsigned issue_flags); diff --git a/io_uring/uring_cmd.c b/io_uring/uring_cmd.c index d1e3ba62ee8e..07730ced9449 100644 --- a/io_uring/uring_cmd.c +++ b/io_uring/uring_cmd.c @@ -292,6 +292,19 @@ int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, } EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed); +int io_uring_cmd_import_fixed_full(int rw, struct iov_iter *iter, + struct io_uring_cmd *ioucmd, + unsigned int issue_flags) +{ + struct io_kiocb *req = cmd_to_io_kiocb(ioucmd); + + if (WARN_ON_ONCE(!(ioucmd->flags & IORING_URING_CMD_FIXED))) + return -EINVAL; + + return io_import_reg_buf_full(req, iter, rw, issue_flags); +} +EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed_full); + int io_uring_cmd_import_fixed_vec(struct io_uring_cmd *ioucmd, const struct iovec __user *uvec, size_t uvec_segs, -- 2.47.3