1*453b329bSJens Axboe // SPDX-License-Identifier: GPL-2.0 2*453b329bSJens Axboe #include <linux/kernel.h> 3*453b329bSJens Axboe #include <linux/errno.h> 4*453b329bSJens Axboe #include <linux/file.h> 5*453b329bSJens Axboe #include <linux/mm.h> 6*453b329bSJens Axboe #include <linux/slab.h> 7*453b329bSJens Axboe #include <linux/io_uring.h> 8*453b329bSJens Axboe 9*453b329bSJens Axboe #include <uapi/linux/io_uring.h> 10*453b329bSJens Axboe 11*453b329bSJens Axboe #include "io_uring_types.h" 12*453b329bSJens Axboe #include "io_uring.h" 13*453b329bSJens Axboe 14*453b329bSJens Axboe int io_file_bitmap_get(struct io_ring_ctx *ctx) 15*453b329bSJens Axboe { 16*453b329bSJens Axboe struct io_file_table *table = &ctx->file_table; 17*453b329bSJens Axboe unsigned long nr = ctx->nr_user_files; 18*453b329bSJens Axboe int ret; 19*453b329bSJens Axboe 20*453b329bSJens Axboe do { 21*453b329bSJens Axboe ret = find_next_zero_bit(table->bitmap, nr, table->alloc_hint); 22*453b329bSJens Axboe if (ret != nr) 23*453b329bSJens Axboe return ret; 24*453b329bSJens Axboe 25*453b329bSJens Axboe if (!table->alloc_hint) 26*453b329bSJens Axboe break; 27*453b329bSJens Axboe 28*453b329bSJens Axboe nr = table->alloc_hint; 29*453b329bSJens Axboe table->alloc_hint = 0; 30*453b329bSJens Axboe } while (1); 31*453b329bSJens Axboe 32*453b329bSJens Axboe return -ENFILE; 33*453b329bSJens Axboe } 34*453b329bSJens Axboe 35*453b329bSJens Axboe bool io_alloc_file_tables(struct io_file_table *table, unsigned nr_files) 36*453b329bSJens Axboe { 37*453b329bSJens Axboe table->files = kvcalloc(nr_files, sizeof(table->files[0]), 38*453b329bSJens Axboe GFP_KERNEL_ACCOUNT); 39*453b329bSJens Axboe if (unlikely(!table->files)) 40*453b329bSJens Axboe return false; 41*453b329bSJens Axboe 42*453b329bSJens Axboe table->bitmap = bitmap_zalloc(nr_files, GFP_KERNEL_ACCOUNT); 43*453b329bSJens Axboe if (unlikely(!table->bitmap)) { 44*453b329bSJens Axboe kvfree(table->files); 45*453b329bSJens Axboe return false; 46*453b329bSJens Axboe } 47*453b329bSJens Axboe 48*453b329bSJens Axboe return true; 49*453b329bSJens Axboe } 50*453b329bSJens Axboe 51*453b329bSJens Axboe void io_free_file_tables(struct io_file_table *table) 52*453b329bSJens Axboe { 53*453b329bSJens Axboe kvfree(table->files); 54*453b329bSJens Axboe bitmap_free(table->bitmap); 55*453b329bSJens Axboe table->files = NULL; 56*453b329bSJens Axboe table->bitmap = NULL; 57*453b329bSJens Axboe } 58