From 600cf3f8b3f68ad22ee9af4cf24b0a96512f7fbe Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Sat, 10 Oct 2020 18:34:15 +0100 Subject: io_uring: refactor *files_register()'s error paths Don't keep repeating cleaning sequences in error paths, write it once in the and use labels. It's less error prone and looks cleaner. Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 78 ++++++++++++++++++++++++----------------------------------- 1 file changed, 32 insertions(+), 46 deletions(-) (limited to 'fs') diff --git a/fs/io_uring.c b/fs/io_uring.c index c3ca82f20f3d..fc4ef725ae09 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -7282,10 +7282,9 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, unsigned nr_args) { __s32 __user *fds = (__s32 __user *) arg; - unsigned nr_tables; + unsigned nr_tables, i; struct file *file; - int fd, ret = 0; - unsigned i; + int fd, ret = -ENOMEM; struct fixed_file_ref_node *ref_node; struct fixed_file_data *file_data; @@ -7307,45 +7306,32 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, nr_tables = DIV_ROUND_UP(nr_args, IORING_MAX_FILES_TABLE); file_data->table = kcalloc(nr_tables, sizeof(file_data->table), GFP_KERNEL); - if (!file_data->table) { - kfree(file_data); - return -ENOMEM; - } + if (!file_data->table) + goto out_free; if (percpu_ref_init(&file_data->refs, io_file_ref_kill, - PERCPU_REF_ALLOW_REINIT, GFP_KERNEL)) { - kfree(file_data->table); - kfree(file_data); - return -ENOMEM; - } + PERCPU_REF_ALLOW_REINIT, GFP_KERNEL)) + goto out_free; - if (io_sqe_alloc_file_tables(file_data, nr_tables, nr_args)) { - percpu_ref_exit(&file_data->refs); - kfree(file_data->table); - kfree(file_data); - return -ENOMEM; - } + if (io_sqe_alloc_file_tables(file_data, nr_tables, nr_args)) + goto out_ref; for (i = 0; i < nr_args; i++, ctx->nr_user_files++) { struct fixed_file_table *table; unsigned index; - ret = -EFAULT; - if (copy_from_user(&fd, &fds[i], sizeof(fd))) - break; + if (copy_from_user(&fd, &fds[i], sizeof(fd))) { + ret = -EFAULT; + goto out_fput; + } /* allow sparse sets */ - if (fd == -1) { - ret = 0; + if (fd == -1) continue; - } - table = &file_data->table[i >> IORING_FILE_TABLE_SHIFT]; - index = i & IORING_FILE_TABLE_MASK; file = fget(fd); - ret = -EBADF; if (!file) - break; + goto out_fput; /* * Don't allow io_uring instances to be registered. If UNIX @@ -7356,28 +7342,13 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, */ if (file->f_op == &io_uring_fops) { fput(file); - break; + goto out_fput; } - ret = 0; + table = &file_data->table[i >> IORING_FILE_TABLE_SHIFT]; + index = i & IORING_FILE_TABLE_MASK; table->files[index] = file; } - if (ret) { - for (i = 0; i < ctx->nr_user_files; i++) { - file = io_file_from_index(ctx, i); - if (file) - fput(file); - } - for (i = 0; i < nr_tables; i++) - kfree(file_data->table[i].files); - - percpu_ref_exit(&file_data->refs); - kfree(file_data->table); - kfree(file_data); - ctx->nr_user_files = 0; - return ret; - } - ctx->file_data = file_data; ret = io_sqe_files_scm(ctx); if (ret) { @@ -7397,6 +7368,21 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, spin_unlock(&file_data->lock); percpu_ref_get(&file_data->refs); return ret; +out_fput: + for (i = 0; i < ctx->nr_user_files; i++) { + file = io_file_from_index(ctx, i); + if (file) + fput(file); + } + for (i = 0; i < nr_tables; i++) + kfree(file_data->table[i].files); + ctx->nr_user_files = 0; +out_ref: + percpu_ref_exit(&file_data->refs); +out_free: + kfree(file_data->table); + kfree(file_data); + return ret; } static int io_sqe_file_register(struct io_ring_ctx *ctx, struct file *file, -- cgit v1.2.3