io_uring: refactor *files_register()'s error paths
authorPavel Begunkov <asml.silence@gmail.com>
Sat, 10 Oct 2020 17:34:15 +0000 (18:34 +0100)
committerJens Axboe <axboe@kernel.dk>
Sat, 10 Oct 2020 18:49:25 +0000 (12:49 -0600)
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 <asml.silence@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/io_uring.c

index c3ca82f20f3d71b174deac924d16e4458fd6e18c..fc4ef725ae095da9ca147abddf6cce1d64b1e345 100644 (file)
@@ -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,