Skip to content

Commit 7481fd9

Browse files
krismanaxboe
authored andcommitted
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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent bb6aaf7 commit 7481fd9

File tree

4 files changed

+53
-0
lines changed

4 files changed

+53
-0
lines changed

include/uapi/linux/io_uring.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ enum io_uring_op {
257257
IORING_OP_FUTEX_WAITV,
258258
IORING_OP_FIXED_FD_INSTALL,
259259
IORING_OP_FTRUNCATE,
260+
IORING_OP_BIND,
260261

261262
/* this goes last, obviously */
262263
IORING_OP_LAST,

io_uring/net.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ struct io_connect {
5151
bool seen_econnaborted;
5252
};
5353

54+
struct io_bind {
55+
struct file *file;
56+
int addr_len;
57+
};
58+
5459
struct io_sr_msg {
5560
struct file *file;
5661
union {
@@ -1715,6 +1720,37 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags)
17151720
return IOU_OK;
17161721
}
17171722

1723+
int io_bind_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
1724+
{
1725+
struct io_bind *bind = io_kiocb_to_cmd(req, struct io_bind);
1726+
struct sockaddr __user *uaddr;
1727+
struct io_async_msghdr *io;
1728+
1729+
if (sqe->len || sqe->buf_index || sqe->rw_flags || sqe->splice_fd_in)
1730+
return -EINVAL;
1731+
1732+
uaddr = u64_to_user_ptr(READ_ONCE(sqe->addr));
1733+
bind->addr_len = READ_ONCE(sqe->addr2);
1734+
1735+
io = io_msg_alloc_async(req);
1736+
if (unlikely(!io))
1737+
return -ENOMEM;
1738+
return move_addr_to_kernel(uaddr, bind->addr_len, &io->addr);
1739+
}
1740+
1741+
int io_bind(struct io_kiocb *req, unsigned int issue_flags)
1742+
{
1743+
struct io_bind *bind = io_kiocb_to_cmd(req, struct io_bind);
1744+
struct io_async_msghdr *io = req->async_data;
1745+
int ret;
1746+
1747+
ret = __sys_bind_socket(sock_from_file(req->file), &io->addr, bind->addr_len);
1748+
if (ret < 0)
1749+
req_set_fail(req);
1750+
io_req_set_res(req, ret, 0);
1751+
return 0;
1752+
}
1753+
17181754
void io_netmsg_cache_free(const void *entry)
17191755
{
17201756
struct io_async_msghdr *kmsg = (struct io_async_msghdr *) entry;

io_uring/net.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ int io_sendmsg_zc(struct io_kiocb *req, unsigned int issue_flags);
4949
int io_send_zc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
5050
void io_send_zc_cleanup(struct io_kiocb *req);
5151

52+
int io_bind_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
53+
int io_bind(struct io_kiocb *req, unsigned int issue_flags);
54+
5255
void io_netmsg_cache_free(const void *entry);
5356
#else
5457
static inline void io_netmsg_cache_free(const void *entry)

io_uring/opdef.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,16 @@ const struct io_issue_def io_issue_defs[] = {
495495
.prep = io_ftruncate_prep,
496496
.issue = io_ftruncate,
497497
},
498+
[IORING_OP_BIND] = {
499+
#if defined(CONFIG_NET)
500+
.needs_file = 1,
501+
.prep = io_bind_prep,
502+
.issue = io_bind,
503+
.async_size = sizeof(struct io_async_msghdr),
504+
#else
505+
.prep = io_eopnotsupp_prep,
506+
#endif
507+
},
498508
};
499509

500510
const struct io_cold_def io_cold_defs[] = {
@@ -716,6 +726,9 @@ const struct io_cold_def io_cold_defs[] = {
716726
[IORING_OP_FTRUNCATE] = {
717727
.name = "FTRUNCATE",
718728
},
729+
[IORING_OP_BIND] = {
730+
.name = "BIND",
731+
},
719732
};
720733

721734
const char *io_uring_get_opcode(u8 opcode)

0 commit comments

Comments
 (0)