io_uring/cmd: Introduce SOCKET_URING_OP_SETSOCKOPT
authorBreno Leitao <leitao@debian.org>
Mon, 16 Oct 2023 13:47:48 +0000 (06:47 -0700)
committerJens Axboe <axboe@kernel.dk>
Thu, 19 Oct 2023 22:42:03 +0000 (16:42 -0600)
Add initial support for SOCKET_URING_OP_SETSOCKOPT. This new command is
similar to setsockopt. This implementation leverages the function
do_sock_setsockopt(), which is shared with the setsockopt() system call
path.

Important to say that userspace needs to keep the pointer's memory alive
until the operation is completed. I.e, the memory could not be
deallocated before the CQE is returned to userspace.

Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Gabriel Krisman Bertazi <krisman@suse.de>
Link: https://lore.kernel.org/r/20231016134750.1381153-11-leitao@debian.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>
include/uapi/linux/io_uring.h
io_uring/uring_cmd.c

index dcf7272463e9a7baac40aed8102e15d60a0ce20a..0f7f6acd0e5abda9f28c64ce6ed1128452a0a9be 100644 (file)
@@ -743,6 +743,7 @@ enum {
        SOCKET_URING_OP_SIOCINQ         = 0,
        SOCKET_URING_OP_SIOCOUTQ,
        SOCKET_URING_OP_GETSOCKOPT,
+       SOCKET_URING_OP_SETSOCKOPT,
 };
 
 #ifdef __cplusplus
index 8b045830b0d9e12df25135ad722d65e3bce72427..acbc2924ecd211e07c2aec13a96106f0fed63b02 100644 (file)
@@ -240,6 +240,25 @@ static inline int io_uring_cmd_getsockopt(struct socket *sock,
        return optlen;
 }
 
+static inline int io_uring_cmd_setsockopt(struct socket *sock,
+                                         struct io_uring_cmd *cmd,
+                                         unsigned int issue_flags)
+{
+       bool compat = !!(issue_flags & IO_URING_F_COMPAT);
+       int optname, optlen, level;
+       void __user *optval;
+       sockptr_t optval_s;
+
+       optval = u64_to_user_ptr(READ_ONCE(cmd->sqe->optval));
+       optname = READ_ONCE(cmd->sqe->optname);
+       optlen = READ_ONCE(cmd->sqe->optlen);
+       level = READ_ONCE(cmd->sqe->level);
+       optval_s = USER_SOCKPTR(optval);
+
+       return do_sock_setsockopt(sock, compat, level, optname, optval_s,
+                                 optlen);
+}
+
 #if defined(CONFIG_NET)
 int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags)
 {
@@ -264,6 +283,8 @@ int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags)
                return arg;
        case SOCKET_URING_OP_GETSOCKOPT:
                return io_uring_cmd_getsockopt(sock, cmd, issue_flags);
+       case SOCKET_URING_OP_SETSOCKOPT:
+               return io_uring_cmd_setsockopt(sock, cmd, issue_flags);
        default:
                return -EOPNOTSUPP;
        }