Skip to content

Commit

Permalink
io_uring: split out fixed file installation and removal
Browse files Browse the repository at this point in the history
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: Jens Axboe <[email protected]>
  • Loading branch information
axboe committed Jul 25, 2022
1 parent 8fcf4c4 commit f110ed8
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 48 deletions.
66 changes: 51 additions & 15 deletions io_uring/filetable.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,10 @@ void io_free_file_tables(struct io_file_table *table)
table->bitmap = NULL;
}

static int io_install_fixed_file(struct io_kiocb *req, struct file *file,
unsigned int issue_flags, u32 slot_index)
static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file,
u32 slot_index)
__must_hold(&req->ctx->uring_lock)
{
struct io_ring_ctx *ctx = req->ctx;
bool needs_switch = false;
struct io_fixed_file *file_slot;
int ret;
Expand Down Expand Up @@ -108,34 +107,71 @@ static int io_install_fixed_file(struct io_kiocb *req, struct file *file,
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)
int __io_fixed_fd_install(struct io_ring_ctx *ctx, struct file *file,
unsigned int file_slot)
{
bool alloc_slot = file_slot == IORING_FILE_INDEX_ALLOC;
struct io_ring_ctx *ctx = req->ctx;
int ret;

io_ring_submit_lock(ctx, issue_flags);

if (alloc_slot) {
ret = io_file_bitmap_get(ctx);
if (unlikely(ret < 0))
goto err;
return ret;
file_slot = ret;
} else {
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)
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);

if (unlikely(ret < 0))
fput(file);
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;
}
3 changes: 3 additions & 0 deletions io_uring/filetable.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
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);

Expand Down
35 changes: 4 additions & 31 deletions io_uring/openclose.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,50 +173,23 @@ void io_open_cleanup(struct io_kiocb *req)
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)
{
struct io_ring_ctx *ctx = req->ctx;
struct io_fixed_file *file_slot;
struct file *file;
int ret;

io_ring_submit_lock(ctx, issue_flags);
ret = -ENXIO;
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:
ret = io_fixed_fd_remove(ctx, offset);
io_ring_submit_unlock(ctx, issue_flags);

return ret;
}

static inline int io_close_fixed(struct io_kiocb *req, unsigned int issue_flags)
{
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)
Expand Down
2 changes: 1 addition & 1 deletion io_uring/openclose.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// 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);

int io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
Expand Down
2 changes: 1 addition & 1 deletion io_uring/rsrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,7 @@ static int io_files_update_with_index_alloc(struct io_kiocb *req,
if (ret < 0)
break;
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;
break;
}
Expand Down

0 comments on commit f110ed8

Please sign in to comment.