Skip to content

Commit 453b329

Browse files
committed
io_uring: separate out file table handling code
Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent f4c163d commit 453b329

File tree

5 files changed

+117
-93
lines changed

5 files changed

+117
-93
lines changed

io_uring/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
# Makefile for io_uring
44

55
obj-$(CONFIG_IO_URING) += io_uring.o xattr.o nop.o fs.o splice.o \
6-
sync.o advise.o
6+
sync.o advise.o filetable.o
77
obj-$(CONFIG_IO_WQ) += io-wq.o

io_uring/filetable.c

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

io_uring/filetable.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#ifndef IOU_FILE_TABLE_H
3+
#define IOU_FILE_TABLE_H
4+
5+
struct io_ring_ctx;
6+
7+
/*
8+
* FFS_SCM is only available on 64-bit archs, for 32-bit we just define it as 0
9+
* and define IO_URING_SCM_ALL. For this case, we use SCM for all files as we
10+
* can't safely always dereference the file when the task has exited and ring
11+
* cleanup is done. If a file is tracked and part of SCM, then unix gc on
12+
* process exit may reap it before __io_sqe_files_unregister() is run.
13+
*/
14+
#define FFS_NOWAIT 0x1UL
15+
#define FFS_ISREG 0x2UL
16+
#if defined(CONFIG_64BIT)
17+
#define FFS_SCM 0x4UL
18+
#else
19+
#define IO_URING_SCM_ALL
20+
#define FFS_SCM 0x0UL
21+
#endif
22+
#define FFS_MASK ~(FFS_NOWAIT|FFS_ISREG|FFS_SCM)
23+
24+
struct io_fixed_file {
25+
/* file * with additional FFS_* flags */
26+
unsigned long file_ptr;
27+
};
28+
29+
struct io_file_table {
30+
struct io_fixed_file *files;
31+
unsigned long *bitmap;
32+
unsigned int alloc_hint;
33+
};
34+
35+
bool io_alloc_file_tables(struct io_file_table *table, unsigned nr_files);
36+
void io_free_file_tables(struct io_file_table *table);
37+
int io_file_bitmap_get(struct io_ring_ctx *ctx);
38+
39+
static inline void io_file_bitmap_clear(struct io_file_table *table, int bit)
40+
{
41+
__clear_bit(bit, table->bitmap);
42+
table->alloc_hint = bit;
43+
}
44+
45+
static inline void io_file_bitmap_set(struct io_file_table *table, int bit)
46+
{
47+
WARN_ON_ONCE(test_bit(bit, table->bitmap));
48+
__set_bit(bit, table->bitmap);
49+
table->alloc_hint = bit + 1;
50+
}
51+
52+
static inline struct io_fixed_file *
53+
io_fixed_file_slot(struct io_file_table *table, unsigned i)
54+
{
55+
return &table->files[i];
56+
}
57+
58+
#endif

io_uring/io_uring.c

Lines changed: 0 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -146,28 +146,6 @@ struct io_overflow_cqe {
146146
struct io_uring_cqe cqe;
147147
};
148148

149-
/*
150-
* FFS_SCM is only available on 64-bit archs, for 32-bit we just define it as 0
151-
* and define IO_URING_SCM_ALL. For this case, we use SCM for all files as we
152-
* can't safely always dereference the file when the task has exited and ring
153-
* cleanup is done. If a file is tracked and part of SCM, then unix gc on
154-
* process exit may reap it before __io_sqe_files_unregister() is run.
155-
*/
156-
#define FFS_NOWAIT 0x1UL
157-
#define FFS_ISREG 0x2UL
158-
#if defined(CONFIG_64BIT)
159-
#define FFS_SCM 0x4UL
160-
#else
161-
#define IO_URING_SCM_ALL
162-
#define FFS_SCM 0x0UL
163-
#endif
164-
#define FFS_MASK ~(FFS_NOWAIT|FFS_ISREG|FFS_SCM)
165-
166-
struct io_fixed_file {
167-
/* file * with additional FFS_* flags */
168-
unsigned long file_ptr;
169-
};
170-
171149
struct io_rsrc_put {
172150
struct list_head list;
173151
u64 tag;
@@ -3983,27 +3961,6 @@ static int io_openat2_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
39833961
return __io_openat_prep(req, sqe);
39843962
}
39853963

3986-
static int io_file_bitmap_get(struct io_ring_ctx *ctx)
3987-
{
3988-
struct io_file_table *table = &ctx->file_table;
3989-
unsigned long nr = ctx->nr_user_files;
3990-
int ret;
3991-
3992-
do {
3993-
ret = find_next_zero_bit(table->bitmap, nr, table->alloc_hint);
3994-
if (ret != nr)
3995-
return ret;
3996-
3997-
if (!table->alloc_hint)
3998-
break;
3999-
4000-
nr = table->alloc_hint;
4001-
table->alloc_hint = 0;
4002-
} while (1);
4003-
4004-
return -ENFILE;
4005-
}
4006-
40073964
/*
40083965
* Note when io_fixed_fd_install() returns error value, it will ensure
40093966
* fput() is called correspondingly.
@@ -6832,12 +6789,6 @@ static void io_wq_submit_work(struct io_wq_work *work)
68326789
io_req_task_queue_fail(req, ret);
68336790
}
68346791

6835-
static inline struct io_fixed_file *io_fixed_file_slot(struct io_file_table *table,
6836-
unsigned i)
6837-
{
6838-
return &table->files[i];
6839-
}
6840-
68416792
static inline struct file *io_file_from_index(struct io_ring_ctx *ctx,
68426793
int index)
68436794
{
@@ -7934,43 +7885,6 @@ static __cold int io_rsrc_data_alloc(struct io_ring_ctx *ctx, rsrc_put_fn *do_pu
79347885
return ret;
79357886
}
79367887

7937-
static bool io_alloc_file_tables(struct io_file_table *table, unsigned nr_files)
7938-
{
7939-
table->files = kvcalloc(nr_files, sizeof(table->files[0]),
7940-
GFP_KERNEL_ACCOUNT);
7941-
if (unlikely(!table->files))
7942-
return false;
7943-
7944-
table->bitmap = bitmap_zalloc(nr_files, GFP_KERNEL_ACCOUNT);
7945-
if (unlikely(!table->bitmap)) {
7946-
kvfree(table->files);
7947-
return false;
7948-
}
7949-
7950-
return true;
7951-
}
7952-
7953-
static void io_free_file_tables(struct io_file_table *table)
7954-
{
7955-
kvfree(table->files);
7956-
bitmap_free(table->bitmap);
7957-
table->files = NULL;
7958-
table->bitmap = NULL;
7959-
}
7960-
7961-
static inline void io_file_bitmap_set(struct io_file_table *table, int bit)
7962-
{
7963-
WARN_ON_ONCE(test_bit(bit, table->bitmap));
7964-
__set_bit(bit, table->bitmap);
7965-
table->alloc_hint = bit + 1;
7966-
}
7967-
7968-
static inline void io_file_bitmap_clear(struct io_file_table *table, int bit)
7969-
{
7970-
__clear_bit(bit, table->bitmap);
7971-
table->alloc_hint = bit;
7972-
}
7973-
79747888
static void __io_sqe_files_unregister(struct io_ring_ctx *ctx)
79757889
{
79767890
#if !defined(IO_URING_SCM_ALL)

io_uring/io_uring_types.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <linux/task_work.h>
66

77
#include "io-wq.h"
8+
#include "filetable.h"
89

910
struct io_uring {
1011
u32 head ____cacheline_aligned_in_smp;
@@ -122,12 +123,6 @@ struct io_ev_fd {
122123
struct rcu_head rcu;
123124
};
124125

125-
struct io_file_table {
126-
struct io_fixed_file *files;
127-
unsigned long *bitmap;
128-
unsigned int alloc_hint;
129-
};
130-
131126
struct io_ring_ctx {
132127
/* const or read-mostly hot data */
133128
struct {

0 commit comments

Comments
 (0)