Add can_retarget_rsrc handler for recv/recvmsg Signed-off-by: Dylan Yudaken <dylany@xxxxxxxx> --- io_uring/net.c | 22 +++++++++++++++++++++- io_uring/net.h | 1 + io_uring/opdef.c | 2 ++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/io_uring/net.c b/io_uring/net.c index f4638e79a022..0fa05ef52dd3 100644 --- a/io_uring/net.c +++ b/io_uring/net.c @@ -70,6 +70,11 @@ struct io_send_zc_msg { struct io_kiocb *notif; }; +struct io_recv_msg { + struct io_sr_msg sr; + int retarget_fd; +}; + #define IO_APOLL_MULTI_POLLED (REQ_F_APOLL_MULTISHOT | REQ_F_POLLED) @@ -547,7 +552,8 @@ int io_recvmsg_prep_async(struct io_kiocb *req) int io_recvmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) { - struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg); + struct io_recv_msg *rcv = io_kiocb_to_cmd(req, struct io_recv_msg); + struct io_sr_msg *sr = &rcv->sr; if (unlikely(sqe->file_index || sqe->addr2)) return -EINVAL; @@ -572,6 +578,11 @@ int io_recvmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) req->flags |= REQ_F_APOLL_MULTISHOT; } + if (req->flags & REQ_F_FIXED_FILE) + rcv->retarget_fd = req->cqe.fd; + else + rcv->retarget_fd = -1; + #ifdef CONFIG_COMPAT if (req->ctx->compat) sr->msg_flags |= MSG_CMSG_COMPAT; @@ -709,6 +720,15 @@ static int io_recvmsg_multishot(struct socket *sock, struct io_sr_msg *io, kmsg->controllen + err; } +bool io_recv_can_retarget_rsrc(struct io_kiocb *req) +{ + struct io_recv_msg *rcv = io_kiocb_to_cmd(req, struct io_recv_msg); + + if (rcv->retarget_fd < 0) + return false; + return io_file_peek_fixed(req, rcv->retarget_fd) == req->file; +} + int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags) { struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg); diff --git a/io_uring/net.h b/io_uring/net.h index 5ffa11bf5d2e..6b5719084494 100644 --- a/io_uring/net.h +++ b/io_uring/net.h @@ -43,6 +43,7 @@ int io_recvmsg_prep_async(struct io_kiocb *req); int io_recvmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe); int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags); int io_recv(struct io_kiocb *req, unsigned int issue_flags); +bool io_recv_can_retarget_rsrc(struct io_kiocb *req); void io_sendrecv_fail(struct io_kiocb *req); diff --git a/io_uring/opdef.c b/io_uring/opdef.c index 83dc0f9ad3b2..1a0be5681c7b 100644 --- a/io_uring/opdef.c +++ b/io_uring/opdef.c @@ -178,6 +178,7 @@ const struct io_op_def io_op_defs[] = { .prep_async = io_recvmsg_prep_async, .cleanup = io_sendmsg_recvmsg_cleanup, .fail = io_sendrecv_fail, + .can_retarget_rsrc = io_recv_can_retarget_rsrc, #else .prep = io_eopnotsupp_prep, #endif @@ -340,6 +341,7 @@ const struct io_op_def io_op_defs[] = { .prep = io_recvmsg_prep, .issue = io_recv, .fail = io_sendrecv_fail, + .can_retarget_rsrc = io_recv_can_retarget_rsrc, #else .prep = io_eopnotsupp_prep, #endif -- 2.30.2