From 2b358604aa6e8c12d7efa14777fcc66c377682b0 Mon Sep 17 00:00:00 2001 From: Bijan Mottahedeh Date: Wed, 6 Jan 2021 12:39:11 -0800 Subject: [PATCH] io_uring: modularize io_sqe_buffers_register Move allocation of buffer management structures, and validation of buffers into separate routines. Reviewed-by: Pavel Begunkov Signed-off-by: Bijan Mottahedeh Signed-off-by: Jens Axboe --- fs/io_uring.c | 51 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index ec70ba0..4cdf0f9 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -8579,13 +8579,8 @@ done: return ret; } -static int io_sqe_buffers_register(struct io_ring_ctx *ctx, void __user *arg, - unsigned int nr_args) +static int io_buffers_map_alloc(struct io_ring_ctx *ctx, unsigned int nr_args) { - int i, ret; - struct iovec iov; - struct page *last_hpage = NULL; - if (ctx->user_bufs) return -EBUSY; if (!nr_args || nr_args > UIO_MAXIOV) @@ -8596,6 +8591,37 @@ static int io_sqe_buffers_register(struct io_ring_ctx *ctx, void __user *arg, if (!ctx->user_bufs) return -ENOMEM; + return 0; +} + +static int io_buffer_validate(struct iovec *iov) +{ + /* + * Don't impose further limits on the size and buffer + * constraints here, we'll -EINVAL later when IO is + * submitted if they are wrong. + */ + if (!iov->iov_base || !iov->iov_len) + return -EFAULT; + + /* arbitrary limit, but we need something */ + if (iov->iov_len > SZ_1G) + return -EFAULT; + + return 0; +} + +static int io_sqe_buffers_register(struct io_ring_ctx *ctx, void __user *arg, + unsigned int nr_args) +{ + int i, ret; + struct iovec iov; + struct page *last_hpage = NULL; + + ret = io_buffers_map_alloc(ctx, nr_args); + if (ret) + return ret; + for (i = 0; i < nr_args; i++) { struct io_mapped_ubuf *imu = &ctx->user_bufs[i]; @@ -8603,17 +8629,8 @@ static int io_sqe_buffers_register(struct io_ring_ctx *ctx, void __user *arg, if (ret) break; - /* - * Don't impose further limits on the size and buffer - * constraints here, we'll -EINVAL later when IO is - * submitted if they are wrong. - */ - ret = -EFAULT; - if (!iov.iov_base || !iov.iov_len) - break; - - /* arbitrary limit, but we need something */ - if (iov.iov_len > SZ_1G) + ret = io_buffer_validate(&iov); + if (ret) break; ret = io_sqe_buffer_register(ctx, &iov, imu, &last_hpage); -- 2.7.4