From 76aaf945701ce736d39447ea0ce5924ef68bc186 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 29 Oct 2024 18:06:53 -0600 Subject: [PATCH] io_uring/rsrc: add request -> io_rsrc_node mapper Signed-off-by: Jens Axboe --- io_uring/rsrc.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ io_uring/rsrc.h | 6 +++++ 2 files changed, 67 insertions(+) diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index 9791f70d5d86..4362a3ad56ec 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include @@ -461,6 +463,9 @@ void io_free_rsrc_node(struct io_rsrc_node *node) if (node->buf) io_buffer_unmap(node->ctx, node); break; + case IORING_RSRC_KBUFFER: + node->kbuf_fn(node); + break; default: WARN_ON_ONCE(1); break; @@ -1079,6 +1084,62 @@ int io_register_clone_buffers(struct io_ring_ctx *ctx, void __user *arg) return ret; } +struct io_rsrc_node *io_rsrc_map_request(struct io_ring_ctx *ctx, + struct request *req, + void (*kbuf_fn)(struct io_rsrc_node *)) +{ + struct io_mapped_ubuf *imu = NULL; + struct io_rsrc_node *node = NULL; + struct req_iterator rq_iter; + struct bio_vec bv; + int nr_bvecs; + + if (!bio_has_data(req->bio)) + goto out; + + nr_bvecs = 0; + rq_for_each_bvec(bv, req, rq_iter) + nr_bvecs++; + if (!nr_bvecs) + goto out; + + node = io_rsrc_node_alloc(ctx, IORING_RSRC_KBUFFER); + if (!node) + goto out; + node->buf = NULL; + + imu = kvmalloc(struct_size(imu, bvec, nr_bvecs), GFP_NOIO); + if (!imu) + goto out; + + imu->ubuf = 0; + imu->len = 0; + if (req->bio != req->biotail) { + int idx = 0; + + rq_for_each_bvec(bv, req, rq_iter) { + imu->bvec[idx++] = bv; + imu->len += bv.bv_len; + } + } else { + struct bio *bio = req->bio; + + imu->bvec[0] = *__bvec_iter_bvec(bio->bi_io_vec, bio->bi_iter); + imu->len = imu->bvec[0].bv_len; + } + imu->nr_bvecs = nr_bvecs; + imu->folio_shift = PAGE_SHIFT; + refcount_set(&imu->refs, 1); + node->buf = imu; + node->kbuf_fn = kbuf_fn; + return node; +out: + if (node) + io_put_rsrc_node(node); + kfree(imu); + return NULL; +} + int io_local_buf_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) { struct io_ring_ctx *ctx = req->ctx; diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h index b0cd0a644ea2..1f968315a33f 100644 --- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -11,6 +11,7 @@ enum { IORING_RSRC_FILE = 0, IORING_RSRC_BUFFER = 1, + IORING_RSRC_KBUFFER = 2, }; struct io_rsrc_node { @@ -19,6 +20,7 @@ struct io_rsrc_node { u16 type; u64 tag; + void (*kbuf_fn)(struct io_rsrc_node *); union { unsigned long file_ptr; struct io_mapped_ubuf *buf; @@ -52,6 +54,10 @@ int io_import_fixed(int ddir, struct iov_iter *iter, struct io_mapped_ubuf *imu, u64 buf_addr, size_t len); +struct io_rsrc_node *io_rsrc_map_request(struct io_ring_ctx *ctx, + struct request *req, + void (*kbuf_fn)(struct io_rsrc_node *)); + int io_register_clone_buffers(struct io_ring_ctx *ctx, void __user *arg); int io_sqe_buffers_unregister(struct io_ring_ctx *ctx); int io_sqe_buffers_register(struct io_ring_ctx *ctx, void __user *arg, -- 2.25.1