xref: /openbmc/linux/io_uring/filetable.c (revision 453b329b)
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