]> www.infradead.org Git - users/willy/xarray.git/commitdiff
io_uring: Introduce IORING_OP_LISTEN
authorGabriel Krisman Bertazi <krisman@suse.de>
Fri, 14 Jun 2024 16:30:47 +0000 (12:30 -0400)
committerJens Axboe <axboe@kernel.dk>
Wed, 19 Jun 2024 13:57:21 +0000 (07:57 -0600)
IORING_OP_LISTEN provides the semantic of listen(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-4-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 4ef153d95c875e3001c4a1bb9b8952f0a388453a..2aaf7ee256ac42d9287ea948dedb5b81325cfbcb 100644 (file)
@@ -258,6 +258,7 @@ enum io_uring_op {
        IORING_OP_FIXED_FD_INSTALL,
        IORING_OP_FTRUNCATE,
        IORING_OP_BIND,
+       IORING_OP_LISTEN,
 
        /* this goes last, obviously */
        IORING_OP_LAST,
index 8cc4cfc2fef3127d4b65cffe1a0c5abe998b6a23..db4a4a03ce3ab6151dbaaafe98326ab3e3801532 100644 (file)
@@ -56,6 +56,11 @@ struct io_bind {
        int                             addr_len;
 };
 
+struct io_listen {
+       struct file                     *file;
+       int                             backlog;
+};
+
 struct io_sr_msg {
        struct file                     *file;
        union {
@@ -1751,6 +1756,29 @@ int io_bind(struct io_kiocb *req, unsigned int issue_flags)
        return 0;
 }
 
+int io_listen_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+{
+       struct io_listen *listen = io_kiocb_to_cmd(req, struct io_listen);
+
+       if (sqe->addr || sqe->buf_index || sqe->rw_flags || sqe->splice_fd_in || sqe->addr2)
+               return -EINVAL;
+
+       listen->backlog = READ_ONCE(sqe->len);
+       return 0;
+}
+
+int io_listen(struct io_kiocb *req, unsigned int issue_flags)
+{
+       struct io_listen *listen = io_kiocb_to_cmd(req, struct io_listen);
+       int ret;
+
+       ret = __sys_listen_socket(sock_from_file(req->file), listen->backlog);
+       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 49f9a7bc1113908c06ade53bdda0264b9088e2d5..52bfee05f06a14ea3df09b94ab0b26f2afad4e20 100644 (file)
@@ -52,6 +52,9 @@ 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);
 
+int io_listen_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
+int io_listen(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 1424c2d9e9ef2d9707f903ce67870f8f7db0be38..2dd49cf22f642de056cb1d30715610bbc7ede22c 100644 (file)
@@ -503,6 +503,16 @@ const struct io_issue_def io_issue_defs[] = {
                .async_size             = sizeof(struct io_async_msghdr),
 #else
                .prep                   = io_eopnotsupp_prep,
+#endif
+       },
+       [IORING_OP_LISTEN] = {
+#if defined(CONFIG_NET)
+               .needs_file             = 1,
+               .prep                   = io_listen_prep,
+               .issue                  = io_listen,
+               .async_size             = sizeof(struct io_async_msghdr),
+#else
+               .prep                   = io_eopnotsupp_prep,
 #endif
        },
 };
@@ -729,6 +739,9 @@ const struct io_cold_def io_cold_defs[] = {
        [IORING_OP_BIND] = {
                .name                   = "BIND",
        },
+       [IORING_OP_LISTEN] = {
+               .name                   = "LISTEN",
+       },
 };
 
 const char *io_uring_get_opcode(u8 opcode)