In preparation to following changes, instead of passing an iovec for
buffer registration introduce a new structure. It'll be moved to uapi
later, but for now it's initialised early from a user provided iovec.

Signed-off-by: Pavel Begunkov <[email protected]>
---
 io_uring/rsrc.c | 47 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 32 insertions(+), 15 deletions(-)

diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c
index 8d0f2ee24e0c..8af371ba6c06 100644
--- a/io_uring/rsrc.c
+++ b/io_uring/rsrc.c
@@ -27,8 +27,13 @@ struct io_rsrc_update {
        u32                             offset;
 };
 
+struct io_uring_regbuf_desc {
+       __u64 uaddr;
+       __u64 size;
+};
+
 static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx,
-                                                  struct iovec *iov);
+                                                  struct io_uring_regbuf_desc 
*desc);
 
 static int hpage_acct_ref(struct io_ring_ctx *ctx, struct page *hpage,
                          bool *acct_new)
@@ -81,6 +86,15 @@ static bool hpage_acct_unref(struct io_ring_ctx *ctx, struct 
page *hpage)
 
 #define IO_CACHED_BVECS_SEGS   32
 
+static void io_iov_to_regbuf_desc(const struct iovec *iov,
+                                 struct io_uring_regbuf_desc *desc)
+{
+       *desc = (struct io_uring_regbuf_desc) {
+               .uaddr = (u64)(uintptr_t)iov->iov_base,
+               .size = iov->iov_len,
+       };
+}
+
 int __io_account_mem(struct user_struct *user, unsigned long nr_pages)
 {
        unsigned long page_limit, cur_pages, new_pages;
@@ -381,6 +395,7 @@ static int __io_sqe_buffers_update(struct io_ring_ctx *ctx,
                return -EINVAL;
 
        for (done = 0; done < nr_args; done++) {
+               struct io_uring_regbuf_desc desc;
                struct io_rsrc_node *node;
                u64 tag = 0;
 
@@ -394,7 +409,9 @@ static int __io_sqe_buffers_update(struct io_ring_ctx *ctx,
                        err = -EFAULT;
                        break;
                }
-               node = io_sqe_buffer_register(ctx, iov);
+
+               io_iov_to_regbuf_desc(iov, &desc);
+               node = io_sqe_buffer_register(ctx, &desc);
                if (IS_ERR(node)) {
                        err = PTR_ERR(node);
                        break;
@@ -853,26 +870,26 @@ bool io_check_coalesce_buffer(struct page **page_array, 
int nr_pages,
 }
 
 static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx,
-                                                  struct iovec *iov)
+                                                  struct io_uring_regbuf_desc 
*desc)
 {
+       unsigned long uaddr = (unsigned long)desc->uaddr;
+       size_t size = desc->size;
        struct io_mapped_ubuf *imu = NULL;
        struct page **pages = NULL;
        struct io_rsrc_node *node;
        unsigned long off;
-       size_t size;
        int ret, nr_pages, i;
        struct io_imu_folio_data data;
        bool coalesced = false;
 
-       if (!iov->iov_base) {
-               if (iov->iov_len)
+       if (!uaddr) {
+               if (size)
                        return ERR_PTR(-EFAULT);
                /* remove the buffer without installing a new one */
                return NULL;
        }
 
-       ret = io_validate_user_buf_range((unsigned long)iov->iov_base,
-                                        iov->iov_len);
+       ret = io_validate_user_buf_range(uaddr, size);
        if (ret)
                return ERR_PTR(ret);
 
@@ -881,8 +898,7 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct 
io_ring_ctx *ctx,
                return ERR_PTR(-ENOMEM);
 
        ret = -ENOMEM;
-       pages = io_pin_pages((unsigned long) iov->iov_base, iov->iov_len,
-                               &nr_pages);
+       pages = io_pin_pages(uaddr, size, &nr_pages);
        if (IS_ERR(pages)) {
                ret = PTR_ERR(pages);
                pages = NULL;
@@ -904,10 +920,9 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct 
io_ring_ctx *ctx,
        if (ret)
                goto done;
 
-       size = iov->iov_len;
        /* store original address for later verification */
-       imu->ubuf = (unsigned long) iov->iov_base;
-       imu->len = iov->iov_len;
+       imu->ubuf = uaddr;
+       imu->len = size;
        imu->folio_shift = PAGE_SHIFT;
        imu->release = io_release_ubuf;
        imu->priv = imu;
@@ -917,7 +932,7 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct 
io_ring_ctx *ctx,
                imu->folio_shift = data.folio_shift;
        refcount_set(&imu->refs, 1);
 
-       off = (unsigned long)iov->iov_base & ~PAGE_MASK;
+       off = uaddr & ~PAGE_MASK;
        if (coalesced)
                off += data.first_folio_page_idx << PAGE_SHIFT;
 
@@ -969,6 +984,7 @@ int io_sqe_buffers_register(struct io_ring_ctx *ctx, void 
__user *arg,
                memset(iov, 0, sizeof(*iov));
 
        for (i = 0; i < nr_args; i++) {
+               struct io_uring_regbuf_desc desc;
                struct io_rsrc_node *node;
                u64 tag = 0;
 
@@ -992,7 +1008,8 @@ int io_sqe_buffers_register(struct io_ring_ctx *ctx, void 
__user *arg,
                        }
                }
 
-               node = io_sqe_buffer_register(ctx, iov);
+               io_iov_to_regbuf_desc(iov, &desc);
+               node = io_sqe_buffer_register(ctx, &desc);
                if (IS_ERR(node)) {
                        ret = PTR_ERR(node);
                        break;
-- 
2.54.0


Reply via email to