Commit f110ed84 authored by Jens Axboe's avatar Jens Axboe

io_uring: split out fixed file installation and removal

Put it with the filetable code, which is where it belongs. While doing
so, have the helpers take a ctx rather than an io_kiocb. It doesn't make
sense to use a request, as it's not an operation on the request itself.
It applies to the ring itself.
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 8fcf4c48
...@@ -58,11 +58,10 @@ void io_free_file_tables(struct io_file_table *table) ...@@ -58,11 +58,10 @@ void io_free_file_tables(struct io_file_table *table)
table->bitmap = NULL; table->bitmap = NULL;
} }
static int io_install_fixed_file(struct io_kiocb *req, struct file *file, static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file,
unsigned int issue_flags, u32 slot_index) u32 slot_index)
__must_hold(&req->ctx->uring_lock) __must_hold(&req->ctx->uring_lock)
{ {
struct io_ring_ctx *ctx = req->ctx;
bool needs_switch = false; bool needs_switch = false;
struct io_fixed_file *file_slot; struct io_fixed_file *file_slot;
int ret; int ret;
...@@ -108,34 +107,71 @@ static int io_install_fixed_file(struct io_kiocb *req, struct file *file, ...@@ -108,34 +107,71 @@ static int io_install_fixed_file(struct io_kiocb *req, struct file *file,
return ret; return ret;
} }
/* int __io_fixed_fd_install(struct io_ring_ctx *ctx, struct file *file,
* Note when io_fixed_fd_install() returns error value, it will ensure unsigned int file_slot)
* fput() is called correspondingly.
*/
int io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags,
struct file *file, unsigned int file_slot)
{ {
bool alloc_slot = file_slot == IORING_FILE_INDEX_ALLOC; bool alloc_slot = file_slot == IORING_FILE_INDEX_ALLOC;
struct io_ring_ctx *ctx = req->ctx;
int ret; int ret;
io_ring_submit_lock(ctx, issue_flags);
if (alloc_slot) { if (alloc_slot) {
ret = io_file_bitmap_get(ctx); ret = io_file_bitmap_get(ctx);
if (unlikely(ret < 0)) if (unlikely(ret < 0))
goto err; return ret;
file_slot = ret; file_slot = ret;
} else { } else {
file_slot--; file_slot--;
} }
ret = io_install_fixed_file(req, file, issue_flags, file_slot); ret = io_install_fixed_file(ctx, file, file_slot);
if (!ret && alloc_slot) if (!ret && alloc_slot)
ret = file_slot; ret = file_slot;
err: return ret;
}
/*
* Note when io_fixed_fd_install() returns error value, it will ensure
* fput() is called correspondingly.
*/
int io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags,
struct file *file, unsigned int file_slot)
{
struct io_ring_ctx *ctx = req->ctx;
int ret;
io_ring_submit_lock(ctx, issue_flags);
ret = __io_fixed_fd_install(ctx, file, file_slot);
io_ring_submit_unlock(ctx, issue_flags); io_ring_submit_unlock(ctx, issue_flags);
if (unlikely(ret < 0)) if (unlikely(ret < 0))
fput(file); fput(file);
return ret; return ret;
} }
int io_fixed_fd_remove(struct io_ring_ctx *ctx, unsigned int offset)
{
struct io_fixed_file *file_slot;
struct file *file;
int ret;
if (unlikely(!ctx->file_data))
return -ENXIO;
if (offset >= ctx->nr_user_files)
return -EINVAL;
ret = io_rsrc_node_switch_start(ctx);
if (ret)
return ret;
offset = array_index_nospec(offset, ctx->nr_user_files);
file_slot = io_fixed_file_slot(&ctx->file_table, offset);
if (!file_slot->file_ptr)
return -EBADF;
file = (struct file *)(file_slot->file_ptr & FFS_MASK);
ret = io_queue_rsrc_removal(ctx->file_data, offset, ctx->rsrc_node, file);
if (ret)
return ret;
file_slot->file_ptr = 0;
io_file_bitmap_clear(&ctx->file_table, offset);
io_rsrc_node_switch(ctx, ctx->file_data);
return 0;
}
...@@ -29,6 +29,9 @@ void io_free_file_tables(struct io_file_table *table); ...@@ -29,6 +29,9 @@ void io_free_file_tables(struct io_file_table *table);
int io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags, int io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags,
struct file *file, unsigned int file_slot); struct file *file, unsigned int file_slot);
int __io_fixed_fd_install(struct io_ring_ctx *ctx, struct file *file,
unsigned int file_slot);
int io_fixed_fd_remove(struct io_ring_ctx *ctx, unsigned int offset);
unsigned int io_file_get_flags(struct file *file); unsigned int io_file_get_flags(struct file *file);
......
...@@ -173,42 +173,15 @@ void io_open_cleanup(struct io_kiocb *req) ...@@ -173,42 +173,15 @@ void io_open_cleanup(struct io_kiocb *req)
putname(open->filename); putname(open->filename);
} }
int __io_close_fixed(struct io_kiocb *req, unsigned int issue_flags, int __io_close_fixed(struct io_ring_ctx *ctx, unsigned int issue_flags,
unsigned int offset) unsigned int offset)
{ {
struct io_ring_ctx *ctx = req->ctx;
struct io_fixed_file *file_slot;
struct file *file;
int ret; int ret;
io_ring_submit_lock(ctx, issue_flags); io_ring_submit_lock(ctx, issue_flags);
ret = -ENXIO; ret = io_fixed_fd_remove(ctx, offset);
if (unlikely(!ctx->file_data))
goto out;
ret = -EINVAL;
if (offset >= ctx->nr_user_files)
goto out;
ret = io_rsrc_node_switch_start(ctx);
if (ret)
goto out;
offset = array_index_nospec(offset, ctx->nr_user_files);
file_slot = io_fixed_file_slot(&ctx->file_table, offset);
ret = -EBADF;
if (!file_slot->file_ptr)
goto out;
file = (struct file *)(file_slot->file_ptr & FFS_MASK);
ret = io_queue_rsrc_removal(ctx->file_data, offset, ctx->rsrc_node, file);
if (ret)
goto out;
file_slot->file_ptr = 0;
io_file_bitmap_clear(&ctx->file_table, offset);
io_rsrc_node_switch(ctx, ctx->file_data);
ret = 0;
out:
io_ring_submit_unlock(ctx, issue_flags); io_ring_submit_unlock(ctx, issue_flags);
return ret; return ret;
} }
...@@ -216,7 +189,7 @@ static inline int io_close_fixed(struct io_kiocb *req, unsigned int issue_flags) ...@@ -216,7 +189,7 @@ static inline int io_close_fixed(struct io_kiocb *req, unsigned int issue_flags)
{ {
struct io_close *close = io_kiocb_to_cmd(req); struct io_close *close = io_kiocb_to_cmd(req);
return __io_close_fixed(req, issue_flags, close->file_slot - 1); return __io_close_fixed(req->ctx, issue_flags, close->file_slot - 1);
} }
int io_close_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) int io_close_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
......
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
int __io_close_fixed(struct io_kiocb *req, unsigned int issue_flags, int __io_close_fixed(struct io_ring_ctx *ctx, unsigned int issue_flags,
unsigned int offset); unsigned int offset);
int io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe); int io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
......
...@@ -703,7 +703,7 @@ static int io_files_update_with_index_alloc(struct io_kiocb *req, ...@@ -703,7 +703,7 @@ static int io_files_update_with_index_alloc(struct io_kiocb *req,
if (ret < 0) if (ret < 0)
break; break;
if (copy_to_user(&fds[done], &ret, sizeof(ret))) { if (copy_to_user(&fds[done], &ret, sizeof(ret))) {
__io_close_fixed(req, issue_flags, ret); __io_close_fixed(req->ctx, issue_flags, ret);
ret = -EFAULT; ret = -EFAULT;
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment