This has two users and it's about to have a third in a future commit. Reading io_slot_flags() and io_slot_file() outside of io_ring_submit_lock() should be fine after a reference has been acquired, as those are immutable. Signed-off-by: Daniele Di Proietto --- io_uring/io_uring.c | 20 ++++++++++++++++---- io_uring/io_uring.h | 2 ++ io_uring/splice.c | 6 +----- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 9a37035e76c0..726245a28b87 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -1553,22 +1553,34 @@ void io_wq_submit_work(struct io_wq_work *work) io_req_task_queue_fail(req, ret); } -inline struct file *io_file_get_fixed(struct io_kiocb *req, int fd, - unsigned int issue_flags) +inline struct io_rsrc_node *io_file_get_fixed_node(struct io_kiocb *req, int fd, + unsigned int issue_flags) { struct io_ring_ctx *ctx = req->ctx; struct io_rsrc_node *node; - struct file *file = NULL; io_ring_submit_lock(ctx, issue_flags); node = io_rsrc_node_lookup(&ctx->file_table.data, fd); if (node) { node->refs++; + } + io_ring_submit_unlock(ctx, issue_flags); + + return node; +} + +inline struct file *io_file_get_fixed(struct io_kiocb *req, int fd, + unsigned int issue_flags) +{ + struct io_rsrc_node *node; + struct file *file = NULL; + + node = io_file_get_fixed_node(req, fd, issue_flags); + if (node) { req->file_node = node; req->flags |= io_slot_flags(node); file = io_slot_file(node); } - io_ring_submit_unlock(ctx, issue_flags); return file; } diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h index 0fa844faf287..1ed44201fa77 100644 --- a/io_uring/io_uring.h +++ b/io_uring/io_uring.h @@ -170,6 +170,8 @@ void __io_commit_cqring_flush(struct io_ring_ctx *ctx); unsigned io_linked_nr(struct io_kiocb *req); void io_req_track_inflight(struct io_kiocb *req); +struct io_rsrc_node *io_file_get_fixed_node(struct io_kiocb *req, int fd, + unsigned int issue_flags); struct file *io_file_get_normal(struct io_kiocb *req, int fd); struct file *io_file_get_fixed(struct io_kiocb *req, int fd, unsigned issue_flags); diff --git a/io_uring/splice.c b/io_uring/splice.c index e81ebbb91925..3c5021a46e79 100644 --- a/io_uring/splice.c +++ b/io_uring/splice.c @@ -60,22 +60,18 @@ static struct file *io_splice_get_file(struct io_kiocb *req, unsigned int issue_flags) { struct io_splice *sp = io_kiocb_to_cmd(req, struct io_splice); - struct io_ring_ctx *ctx = req->ctx; struct io_rsrc_node *node; struct file *file = NULL; if (!(sp->flags & SPLICE_F_FD_IN_FIXED)) return io_file_get_normal(req, sp->splice_fd_in); - io_ring_submit_lock(ctx, issue_flags); - node = io_rsrc_node_lookup(&ctx->file_table.data, sp->splice_fd_in); + node = io_file_get_fixed_node(req, sp->splice_fd_in, issue_flags); if (node) { - node->refs++; sp->rsrc_node = node; file = io_slot_file(node); req->flags |= REQ_F_NEED_CLEANUP; } - io_ring_submit_unlock(ctx, issue_flags); return file; } -- 2.43.0