ool is_cqe32) { diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index a63474b331bf..a141aaeb099d 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -1151,6 +1151,71 @@ 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_reg_buf_index_get(struct io_kiocb *req, struct iov_iter *iter, + u16 buf_index, unsigned int off, size_t len, + int ddir, unsigned issue_flags) +{ + struct io_ring_ctx *ctx = req->ctx; + struct io_rsrc_node *node; + struct io_mapped_ubuf *imu; + u64 addr; + int err; + + io_ring_submit_lock(ctx, issue_flags); + + node = io_rsrc_node_lookup(&ctx->buf_table, buf_index); + if (!node) { + io_ring_submit_unlock(ctx, issue_flags); + return -EINVAL; + } + + node->refs++; + + io_ring_submit_unlock(ctx, issue_flags); + + imu = node->buf; + if (!imu) { + err = -EFAULT; + goto error; + } + + if (check_add_overflow(imu->ubuf, off, &addr)) { + err = -EINVAL; + goto error; + } + + err = io_import_fixed(ddir, iter, imu, addr, len); + if (err) + goto error; + + return 0; + +error: + io_reg_buf_index_put(req, buf_index, issue_flags); + return err; +} + +int io_reg_buf_index_put(struct io_kiocb *req, u16 buf_index, + unsigned issue_flags) +{ + struct io_ring_ctx *ctx = req->ctx; + struct io_rsrc_node *node; + + io_ring_submit_lock(ctx, issue_flags); + + node = io_rsrc_node_lookup(&ctx->buf_table, buf_index); + if (WARN_ON_ONCE(!node)) { + io_ring_submit_unlock(ctx, issue_flags); + return -EFAULT; + } + + io_put_rsrc_node(ctx, node); + + io_ring_submit_unlock(ctx, issue_flags); + + return 0; +} + /* 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 d603f6a47f5e..16f4bab9582b 100644 --- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -64,6 +64,11 @@ 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_reg_buf_index_get(struct io_kiocb *req, struct iov_iter *iter, + u16 buf_index, unsigned int off, size_t len, + int ddir, unsigned issue_flags); +int io_reg_buf_index_put(struct io_kiocb *req, u16 buf_index, + 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 b6b675010bfd..ee95d1102505 100644 --- a/io_uring/uring_cmd.c +++ b/io_uring/uring_cmd.c @@ -314,6 +314,27 @@ int io_uring_cmd_import_fixed_vec(struct io_uring_cmd *ioucmd, } EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed_vec); +int io_uring_cmd_fixed_index_get(struct io_uring_cmd *ioucmd, u16 buf_index, + unsigned int off, size_t len, int ddir, + struct iov_iter *iter, + unsigned int issue_flags) +{ + struct io_kiocb *req = cmd_to_io_kiocb(ioucmd); + + return io_reg_buf_index_get(req, iter, buf_index, off, len, ddir, + issue_flags); +} +EXPORT_SYMBOL_GPL(io_uring_cmd_fixed_index_get); + +int io_uring_cmd_fixed_index_put(struct io_uring_cmd *ioucmd, u16 buf_index, + unsigned int issue_flags) +{ + struct io_kiocb *req = cmd_to_io_kiocb(ioucmd); + + return io_reg_buf_index_put(req, buf_index, issue_flags); +} +EXPORT_SYMBOL_GPL(io_uring_cmd_fixed_index_put); + void io_uring_cmd_issue_blocking(struct io_uring_cmd *ioucmd) { struct io_kiocb *req = cmd_to_io_kiocb(ioucmd); -- 2.47.3[PATCH v3 08/25] io_uring: add io_uring_cmd_fixed_index_get() and io_uring_cmd_fixed_index_put()Joanne Koong undefinedmiklos@szeredi.hu, axboe@kernel.dk undefined undefined undefined undefined undefined undefined undefined undefined/„×z