@@ -5419,15 +5419,11 @@ static int io_file_bitmap_get(struct io_ring_ctx *ctx)
unsigned long nr = ctx->nr_user_files;
int ret;
- if (table->alloc_hint >= nr)
- table->alloc_hint = 0;
-
do {
ret = find_next_zero_bit(table->bitmap, nr, table->alloc_hint);
- if (ret != nr) {
- table->alloc_hint = ret + 1;
+ if (ret != nr)
return ret;
- }
+
if (!table->alloc_hint)
break;
@@ -9650,12 +9646,13 @@ static void io_free_file_tables(struct io_file_table *table)
table->bitmap = NULL;
}
-static inline void io_file_bitmap_set(struct io_file_table *table, int bit)
+static inline void io_file_bitmap_set(struct io_ring_ctx *ctx, int bit)
{
+ struct io_file_table *table = &ctx->file_table;
+
WARN_ON_ONCE(test_bit(bit, table->bitmap));
__set_bit(bit, table->bitmap);
- if (bit == table->alloc_hint)
- table->alloc_hint++;
+ table->alloc_hint = bit + 1;
}
static inline void io_file_bitmap_clear(struct io_file_table *table, int bit)
@@ -10080,7 +10077,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_file_bitmap_set(ctx, i);
}
io_rsrc_node_switch(ctx, NULL);
@@ -10161,7 +10158,7 @@ static int io_install_fixed_file(struct io_kiocb *req, unsigned int issue_flags,
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);
+ io_file_bitmap_set(ctx, slot_index);
}
err:
if (needs_switch)
@@ -10284,7 +10281,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);
+ io_file_bitmap_set(ctx, i);
}
}
io_file_bitmap_get() returns a free bitmap slot, but if it isn't used later, such as io_queue_rsrc_removal() returns error, in this case, we should not update alloc_hint at all, which still should be considered as a valid candidate for next io_file_bitmap_get() calls. To fix this issue, only update alloc_hint in io_file_bitmap_set(). Signed-off-by: Xiaoguang Wang <xiaoguang.wang@linux.alibaba.com> --- V2: Delete unnecessary check against to alloc_hint. --- fs/io_uring.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-)