diff options
author | Gabriel Krisman Bertazi <krisman@suse.de> | 2024-06-14 12:30:46 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2024-06-19 07:57:21 -0600 |
commit | 7481fd93fa0a851740e26026485f56a1305454ce (patch) | |
tree | cbbf8cdfea0b94d6d85371bad17ab38ee2accad5 /io_uring/net.c | |
parent | bb6aaf736680f0f3c2e6281735c47c64e2042819 (diff) |
io_uring: Introduce IORING_OP_BIND
IORING_OP_BIND provides the semantic of bind(2) via io_uring. While
this is an essentially synchronous system call, the main point is to
enable a network path to execute fully with io_uring registered and
descriptorless files.
Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de>
Link: https://lore.kernel.org/r/20240614163047.31581-3-krisman@suse.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'io_uring/net.c')
-rw-r--r-- | io_uring/net.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/io_uring/net.c b/io_uring/net.c index 7c98c4d50946..8cc4cfc2fef3 100644 --- a/io_uring/net.c +++ b/io_uring/net.c @@ -51,6 +51,11 @@ struct io_connect { bool seen_econnaborted; }; +struct io_bind { + struct file *file; + int addr_len; +}; + struct io_sr_msg { struct file *file; union { @@ -1715,6 +1720,37 @@ out: return IOU_OK; } +int io_bind_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) +{ + struct io_bind *bind = io_kiocb_to_cmd(req, struct io_bind); + struct sockaddr __user *uaddr; + struct io_async_msghdr *io; + + if (sqe->len || sqe->buf_index || sqe->rw_flags || sqe->splice_fd_in) + return -EINVAL; + + uaddr = u64_to_user_ptr(READ_ONCE(sqe->addr)); + bind->addr_len = READ_ONCE(sqe->addr2); + + io = io_msg_alloc_async(req); + if (unlikely(!io)) + return -ENOMEM; + return move_addr_to_kernel(uaddr, bind->addr_len, &io->addr); +} + +int io_bind(struct io_kiocb *req, unsigned int issue_flags) +{ + struct io_bind *bind = io_kiocb_to_cmd(req, struct io_bind); + struct io_async_msghdr *io = req->async_data; + int ret; + + ret = __sys_bind_socket(sock_from_file(req->file), &io->addr, bind->addr_len); + if (ret < 0) + req_set_fail(req); + io_req_set_res(req, ret, 0); + return 0; +} + void io_netmsg_cache_free(const void *entry) { struct io_async_msghdr *kmsg = (struct io_async_msghdr *) entry; |