diff options
author | Pavel Begunkov <asml.silence@gmail.com> | 2021-04-01 15:44:03 +0100 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2021-04-11 19:30:35 -0600 |
commit | 846a4ef22bf6d6ede4547fe8fa500385a90c64ba (patch) | |
tree | cf48bd4060386b4d29f291dd3960b47a73504413 /fs/io_uring.c | |
parent | f4f7d21ce46474128934caeb80dfb1e5396b596e (diff) | |
download | lwn-846a4ef22bf6d6ede4547fe8fa500385a90c64ba.tar.gz lwn-846a4ef22bf6d6ede4547fe8fa500385a90c64ba.zip |
io_uring: refactor file tables alloc/free
Introduce a heler io_free_file_tables() doing all the cleaning, there
are several places where it's hand coded. Also move all allocations into
io_sqe_alloc_file_tables() and rename it, so all of it is in one place.
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/502a84ebf41ff119b095e59661e678eacb752bf8.1617287883.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs/io_uring.c')
-rw-r--r-- | fs/io_uring.c | 52 |
1 files changed, 26 insertions, 26 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c index 4700de36a8cc..663e1cf445ca 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -7054,6 +7054,16 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, return READ_ONCE(rings->cq.head) == READ_ONCE(rings->cq.tail) ? ret : 0; } +static void io_free_file_tables(struct io_rsrc_data *data, unsigned nr_files) +{ + unsigned i, nr_tables = DIV_ROUND_UP(nr_files, IORING_MAX_FILES_TABLE); + + for (i = 0; i < nr_tables; i++) + kfree(data->table[i].files); + kfree(data->table); + data->table = NULL; +} + static void __io_sqe_files_unregister(struct io_ring_ctx *ctx) { #if defined(CONFIG_UNIX) @@ -7190,14 +7200,12 @@ static struct io_rsrc_data *io_rsrc_data_alloc(struct io_ring_ctx *ctx, static void io_rsrc_data_free(struct io_rsrc_data *data) { percpu_ref_exit(&data->refs); - kfree(data->table); kfree(data); } static int io_sqe_files_unregister(struct io_ring_ctx *ctx) { struct io_rsrc_data *data = ctx->file_data; - unsigned nr_tables, i; int ret; if (!data) @@ -7207,9 +7215,7 @@ static int io_sqe_files_unregister(struct io_ring_ctx *ctx) return ret; __io_sqe_files_unregister(ctx); - nr_tables = DIV_ROUND_UP(ctx->nr_user_files, IORING_MAX_FILES_TABLE); - for (i = 0; i < nr_tables; i++) - kfree(data->table[i].files); + io_free_file_tables(data, ctx->nr_user_files); io_rsrc_data_free(data); ctx->file_data = NULL; ctx->nr_user_files = 0; @@ -7439,16 +7445,20 @@ static int io_sqe_files_scm(struct io_ring_ctx *ctx) } #endif -static int io_sqe_alloc_file_tables(struct io_rsrc_data *file_data, - unsigned nr_tables, unsigned nr_files) +static bool io_alloc_file_tables(struct io_rsrc_data *file_data, + unsigned nr_files) { - int i; + unsigned i, nr_tables = DIV_ROUND_UP(nr_files, IORING_MAX_FILES_TABLE); + + file_data->table = kcalloc(nr_tables, sizeof(*file_data->table), + GFP_KERNEL); + if (!file_data->table) + return false; for (i = 0; i < nr_tables; i++) { struct fixed_rsrc_table *table = &file_data->table[i]; - unsigned this_files; + unsigned int this_files = min(nr_files, IORING_MAX_FILES_TABLE); - this_files = min(nr_files, IORING_MAX_FILES_TABLE); table->files = kcalloc(this_files, sizeof(struct file *), GFP_KERNEL); if (!table->files) @@ -7457,13 +7467,10 @@ static int io_sqe_alloc_file_tables(struct io_rsrc_data *file_data, } if (i == nr_tables) - return 0; + return true; - for (i = 0; i < nr_tables; i++) { - struct fixed_rsrc_table *table = &file_data->table[i]; - kfree(table->files); - } - return 1; + io_free_file_tables(file_data, nr_tables * IORING_MAX_FILES_TABLE); + return false; } static void io_rsrc_file_put(struct io_ring_ctx *ctx, struct io_rsrc_put *prsrc) @@ -7613,9 +7620,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, i; struct file *file; int fd, ret; + unsigned i; struct io_rsrc_data *file_data; if (ctx->file_data) @@ -7634,13 +7641,7 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, ctx->file_data = file_data; ret = -ENOMEM; - 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) - goto out_free; - - if (io_sqe_alloc_file_tables(file_data, nr_tables, nr_args)) + if (!io_alloc_file_tables(file_data, nr_args)) goto out_free; for (i = 0; i < nr_args; i++, ctx->nr_user_files++) { @@ -7685,8 +7686,7 @@ out_fput: if (file) fput(file); } - for (i = 0; i < nr_tables; i++) - kfree(file_data->table[i].files); + io_free_file_tables(file_data, nr_args); ctx->nr_user_files = 0; out_free: io_rsrc_data_free(ctx->file_data); |