io_uring: Add io_uring command support for sockets
authorBreno Leitao <leitao@debian.org>
Tue, 27 Jun 2023 13:44:24 +0000 (06:44 -0700)
committerJens Axboe <axboe@kernel.dk>
Wed, 9 Aug 2023 16:46:15 +0000 (10:46 -0600)
Enable io_uring commands on network sockets. Create two new
SOCKET_URING_OP commands that will operate on sockets.

In order to call ioctl on sockets, use the file_operations->io_uring_cmd
callbacks, and map it to a uring socket function, which handles the
SOCKET_URING_OP accordingly, and calls socket ioctls.

This patches was tested by creating a new test case in liburing.
Link: https://github.com/leitao/liburing/tree/io_uring_cmd
Signed-off-by: Breno Leitao <leitao@debian.org>
Acked-by: Jakub Kicinski <kuba@kernel.org>
Link: https://lore.kernel.org/r/20230627134424.2784797-1-leitao@debian.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>
include/linux/io_uring.h
include/uapi/linux/io_uring.h
io_uring/uring_cmd.c
net/socket.c

index bb9c666..106cdc5 100644 (file)
@@ -81,6 +81,7 @@ static inline void io_uring_free(struct task_struct *tsk)
        if (tsk->io_uring)
                __io_uring_free(tsk);
 }
+int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags);
 #else
 static inline int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw,
                              struct iov_iter *iter, void *ioucmd)
@@ -116,6 +117,11 @@ static inline const char *io_uring_get_opcode(u8 opcode)
 {
        return "";
 }
+static inline int io_uring_cmd_sock(struct io_uring_cmd *cmd,
+                                   unsigned int issue_flags)
+{
+       return -EOPNOTSUPP;
+}
 #endif
 
 #endif
index 36f9c73..9fc7195 100644 (file)
@@ -723,6 +723,14 @@ struct io_uring_recvmsg_out {
        __u32 flags;
 };
 
+/*
+ * Argument for IORING_OP_URING_CMD when file is a socket
+ */
+enum {
+       SOCKET_URING_OP_SIOCINQ         = 0,
+       SOCKET_URING_OP_SIOCOUTQ,
+};
+
 #ifdef __cplusplus
 }
 #endif
index 476c787..8e7a03c 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/nospec.h>
 
 #include <uapi/linux/io_uring.h>
+#include <uapi/asm-generic/ioctls.h>
 
 #include "io_uring.h"
 #include "rsrc.h"
@@ -164,3 +165,30 @@ int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw,
        return io_import_fixed(rw, iter, req->imu, ubuf, len);
 }
 EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed);
+
+int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags)
+{
+       struct socket *sock = cmd->file->private_data;
+       struct sock *sk = sock->sk;
+       struct proto *prot = READ_ONCE(sk->sk_prot);
+       int ret, arg = 0;
+
+       if (!prot || !prot->ioctl)
+               return -EOPNOTSUPP;
+
+       switch (cmd->sqe->cmd_op) {
+       case SOCKET_URING_OP_SIOCINQ:
+               ret = prot->ioctl(sk, SIOCINQ, &arg);
+               if (ret)
+                       return ret;
+               return arg;
+       case SOCKET_URING_OP_SIOCOUTQ:
+               ret = prot->ioctl(sk, SIOCOUTQ, &arg);
+               if (ret)
+                       return ret;
+               return arg;
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+EXPORT_SYMBOL_GPL(io_uring_cmd_sock);
index 2b0e54b..1dc23f5 100644 (file)
@@ -88,6 +88,7 @@
 #include <linux/xattr.h>
 #include <linux/nospec.h>
 #include <linux/indirect_call_wrapper.h>
+#include <linux/io_uring.h>
 
 #include <linux/uaccess.h>
 #include <asm/unistd.h>
@@ -159,6 +160,7 @@ static const struct file_operations socket_file_ops = {
 #ifdef CONFIG_COMPAT
        .compat_ioctl = compat_sock_ioctl,
 #endif
+       .uring_cmd =    io_uring_cmd_sock,
        .mmap =         sock_mmap,
        .release =      sock_close,
        .fasync =       sock_fasync,