diff options
author | Jens Axboe <axboe@kernel.dk> | 2022-05-07 18:56:13 +0300 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2022-05-13 15:28:29 +0300 |
commit | d78bd8adfcbc55b9dc01e9034a55b2a61a2124dc (patch) | |
tree | 7bd4c6a2d87b9c24de621585e15214f5ae70215d /fs/io_uring.c | |
parent | 7ccba24d3bc084d891def1a6fea504e4cb327a8c (diff) | |
download | linux-d78bd8adfcbc55b9dc01e9034a55b2a61a2124dc.tar.xz |
io_uring: track fixed files with a bitmap
In preparation for adding a basic allocator for direct descriptors,
add helpers that set/clear whether a file slot is used.
Reviewed-by: Hao Xu <howeyxu@tencent.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs/io_uring.c')
-rw-r--r-- | fs/io_uring.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c index 22699cb359e9..f8a685cc0363 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -257,6 +257,7 @@ struct io_rsrc_put { struct io_file_table { struct io_fixed_file *files; + unsigned long *bitmap; }; struct io_rsrc_node { @@ -7572,6 +7573,7 @@ static inline struct file *io_file_get_fixed(struct io_kiocb *req, int fd, /* mask in overlapping REQ_F and FFS bits */ req->flags |= (file_ptr << REQ_F_SUPPORT_NOWAIT_BIT); io_req_set_rsrc_node(req, ctx, 0); + WARN_ON_ONCE(file && !test_bit(fd, ctx->file_table.bitmap)); out: io_ring_submit_unlock(ctx, issue_flags); return file; @@ -8638,13 +8640,35 @@ static bool io_alloc_file_tables(struct io_file_table *table, unsigned nr_files) { table->files = kvcalloc(nr_files, sizeof(table->files[0]), GFP_KERNEL_ACCOUNT); - return !!table->files; + if (unlikely(!table->files)) + return false; + + table->bitmap = bitmap_zalloc(nr_files, GFP_KERNEL_ACCOUNT); + if (unlikely(!table->bitmap)) { + kvfree(table->files); + return false; + } + + return true; } static void io_free_file_tables(struct io_file_table *table) { kvfree(table->files); + bitmap_free(table->bitmap); table->files = NULL; + table->bitmap = NULL; +} + +static inline void io_file_bitmap_set(struct io_file_table *table, int bit) +{ + WARN_ON_ONCE(test_bit(bit, table->bitmap)); + __set_bit(bit, table->bitmap); +} + +static inline void io_file_bitmap_clear(struct io_file_table *table, int bit) +{ + __clear_bit(bit, table->bitmap); } static void __io_sqe_files_unregister(struct io_ring_ctx *ctx) @@ -8659,6 +8683,7 @@ static void __io_sqe_files_unregister(struct io_ring_ctx *ctx) continue; if (io_fixed_file_slot(&ctx->file_table, i)->file_ptr & FFS_SCM) continue; + io_file_bitmap_clear(&ctx->file_table, i); fput(file); } #endif @@ -9062,6 +9087,7 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, } file_slot = io_fixed_file_slot(&ctx->file_table, i); io_fixed_file_set(file_slot, file); + io_file_bitmap_set(&ctx->file_table, i); } io_rsrc_node_switch(ctx, NULL); @@ -9122,6 +9148,7 @@ static int io_install_fixed_file(struct io_kiocb *req, struct file *file, if (ret) goto err; file_slot->file_ptr = 0; + io_file_bitmap_clear(&ctx->file_table, slot_index); needs_switch = true; } @@ -9129,6 +9156,7 @@ static int io_install_fixed_file(struct io_kiocb *req, struct file *file, if (!ret) { *io_get_tag_slot(ctx->file_data, slot_index) = 0; io_fixed_file_set(file_slot, file); + io_file_bitmap_set(&ctx->file_table, slot_index); } err: if (needs_switch) @@ -9170,6 +9198,7 @@ static int io_close_fixed(struct io_kiocb *req, unsigned int issue_flags) goto out; file_slot->file_ptr = 0; + io_file_bitmap_clear(&ctx->file_table, offset); io_rsrc_node_switch(ctx, ctx->file_data); ret = 0; out: @@ -9219,6 +9248,7 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx, if (err) break; file_slot->file_ptr = 0; + io_file_bitmap_clear(&ctx->file_table, i); needs_switch = true; } if (fd != -1) { @@ -9247,6 +9277,7 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx, } *io_get_tag_slot(data, i) = tag; io_fixed_file_set(file_slot, file); + io_file_bitmap_set(&ctx->file_table, i); } } |