]> www.infradead.org Git - users/hch/block.git/commitdiff
io_uring: Introduce IORING_OP_BIND
authorGabriel Krisman Bertazi <krisman@suse.de>
Fri, 14 Jun 2024 16:30:46 +0000 (12:30 -0400)
committerJens Axboe <axboe@kernel.dk>
Wed, 19 Jun 2024 13:57:21 +0000 (07:57 -0600)
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>
include/uapi/linux/io_uring.h
io_uring/net.c
io_uring/net.h
io_uring/opdef.c

index 994bf7af0efe20afbfc4888413ad5a6d261a0e6e..4ef153d95c875e3001c4a1bb9b8952f0a388453a 100644 (file)
@@ -257,6 +257,7 @@ enum io_uring_op {
        IORING_OP_FUTEX_WAITV,
        IORING_OP_FIXED_FD_INSTALL,
        IORING_OP_FTRUNCATE,
+       IORING_OP_BIND,
 
        /* this goes last, obviously */
        IORING_OP_LAST,
index 7c98c4d5094633cb948bb761d2345e65cfb380f2..8cc4cfc2fef3127d4b65cffe1a0c5abe998b6a23 100644 (file)
@@ -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;
index 0eb1c1920fc9a96723875f43ab6b358228a52484..49f9a7bc1113908c06ade53bdda0264b9088e2d5 100644 (file)
@@ -49,6 +49,9 @@ int io_sendmsg_zc(struct io_kiocb *req, unsigned int issue_flags);
 int io_send_zc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
 void io_send_zc_cleanup(struct io_kiocb *req);
 
+int io_bind_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
+int io_bind(struct io_kiocb *req, unsigned int issue_flags);
+
 void io_netmsg_cache_free(const void *entry);
 #else
 static inline void io_netmsg_cache_free(const void *entry)
index 2e3b7b16effb34154b2be88dc07af5e6e0a4699a..1424c2d9e9ef2d9707f903ce67870f8f7db0be38 100644 (file)
@@ -495,6 +495,16 @@ const struct io_issue_def io_issue_defs[] = {
                .prep                   = io_ftruncate_prep,
                .issue                  = io_ftruncate,
        },
+       [IORING_OP_BIND] = {
+#if defined(CONFIG_NET)
+               .needs_file             = 1,
+               .prep                   = io_bind_prep,
+               .issue                  = io_bind,
+               .async_size             = sizeof(struct io_async_msghdr),
+#else
+               .prep                   = io_eopnotsupp_prep,
+#endif
+       },
 };
 
 const struct io_cold_def io_cold_defs[] = {
@@ -716,6 +726,9 @@ const struct io_cold_def io_cold_defs[] = {
        [IORING_OP_FTRUNCATE] = {
                .name                   = "FTRUNCATE",
        },
+       [IORING_OP_BIND] = {
+               .name                   = "BIND",
+       },
 };
 
 const char *io_uring_get_opcode(u8 opcode)