162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#ifndef IOU_FILE_TABLE_H
362306a36Sopenharmony_ci#define IOU_FILE_TABLE_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/file.h>
662306a36Sopenharmony_ci#include <linux/io_uring_types.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_cibool io_alloc_file_tables(struct io_file_table *table, unsigned nr_files);
962306a36Sopenharmony_civoid io_free_file_tables(struct io_file_table *table);
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ciint io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags,
1262306a36Sopenharmony_ci			struct file *file, unsigned int file_slot);
1362306a36Sopenharmony_ciint __io_fixed_fd_install(struct io_ring_ctx *ctx, struct file *file,
1462306a36Sopenharmony_ci				unsigned int file_slot);
1562306a36Sopenharmony_ciint io_fixed_fd_remove(struct io_ring_ctx *ctx, unsigned int offset);
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ciint io_register_file_alloc_range(struct io_ring_ctx *ctx,
1862306a36Sopenharmony_ci				 struct io_uring_file_index_range __user *arg);
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ciunsigned int io_file_get_flags(struct file *file);
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistatic inline void io_file_bitmap_clear(struct io_file_table *table, int bit)
2362306a36Sopenharmony_ci{
2462306a36Sopenharmony_ci	WARN_ON_ONCE(!test_bit(bit, table->bitmap));
2562306a36Sopenharmony_ci	__clear_bit(bit, table->bitmap);
2662306a36Sopenharmony_ci	table->alloc_hint = bit;
2762306a36Sopenharmony_ci}
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistatic inline void io_file_bitmap_set(struct io_file_table *table, int bit)
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci	WARN_ON_ONCE(test_bit(bit, table->bitmap));
3262306a36Sopenharmony_ci	__set_bit(bit, table->bitmap);
3362306a36Sopenharmony_ci	table->alloc_hint = bit + 1;
3462306a36Sopenharmony_ci}
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_cistatic inline struct io_fixed_file *
3762306a36Sopenharmony_ciio_fixed_file_slot(struct io_file_table *table, unsigned i)
3862306a36Sopenharmony_ci{
3962306a36Sopenharmony_ci	return &table->files[i];
4062306a36Sopenharmony_ci}
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci#define FFS_NOWAIT		0x1UL
4362306a36Sopenharmony_ci#define FFS_ISREG		0x2UL
4462306a36Sopenharmony_ci#define FFS_MASK		~(FFS_NOWAIT|FFS_ISREG)
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistatic inline unsigned int io_slot_flags(struct io_fixed_file *slot)
4762306a36Sopenharmony_ci{
4862306a36Sopenharmony_ci	return (slot->file_ptr & ~FFS_MASK) << REQ_F_SUPPORT_NOWAIT_BIT;
4962306a36Sopenharmony_ci}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cistatic inline struct file *io_slot_file(struct io_fixed_file *slot)
5262306a36Sopenharmony_ci{
5362306a36Sopenharmony_ci	return (struct file *)(slot->file_ptr & FFS_MASK);
5462306a36Sopenharmony_ci}
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_cistatic inline struct file *io_file_from_index(struct io_file_table *table,
5762306a36Sopenharmony_ci					      int index)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci	return io_slot_file(io_fixed_file_slot(table, index));
6062306a36Sopenharmony_ci}
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_cistatic inline void io_fixed_file_set(struct io_fixed_file *file_slot,
6362306a36Sopenharmony_ci				     struct file *file)
6462306a36Sopenharmony_ci{
6562306a36Sopenharmony_ci	file_slot->file_ptr = (unsigned long)file |
6662306a36Sopenharmony_ci		(io_file_get_flags(file) >> REQ_F_SUPPORT_NOWAIT_BIT);
6762306a36Sopenharmony_ci}
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_cistatic inline void io_reset_alloc_hint(struct io_ring_ctx *ctx)
7062306a36Sopenharmony_ci{
7162306a36Sopenharmony_ci	ctx->file_table.alloc_hint = ctx->file_alloc_start;
7262306a36Sopenharmony_ci}
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_cistatic inline void io_file_table_set_alloc_range(struct io_ring_ctx *ctx,
7562306a36Sopenharmony_ci						 unsigned off, unsigned len)
7662306a36Sopenharmony_ci{
7762306a36Sopenharmony_ci	ctx->file_alloc_start = off;
7862306a36Sopenharmony_ci	ctx->file_alloc_end = off + len;
7962306a36Sopenharmony_ci	io_reset_alloc_hint(ctx);
8062306a36Sopenharmony_ci}
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci#endif
83