io_uring: Introduce getsockname io_uring cmd

Introduce a socket-specific io_uring_cmd to support
getsockname/getpeername via io_uring.  I made this an io_uring_cmd
instead of a new operation to avoid polluting the command namespace with
what is exclusively a socket operation.  In addition, since we don't
need to conform to existing interfaces, this merges the
getsockname/getpeername in a single operation, since the implementation
is pretty much the same.

This has been frequently requested, for instance at [1] and more
recently in the project Discord channel. The main use-case is to support
fixed socket file descriptors.

[1] https://github.com/axboe/liburing/issues/1356

Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Gabriel Krisman Bertazi
2025-11-25 16:18:01 -05:00
committed by Jens Axboe
parent d73c167708
commit 5d24321e4c
2 changed files with 23 additions and 0 deletions

View File

@@ -1009,6 +1009,7 @@ enum io_uring_socket_op {
SOCKET_URING_OP_GETSOCKOPT,
SOCKET_URING_OP_SETSOCKOPT,
SOCKET_URING_OP_TX_TIMESTAMP,
SOCKET_URING_OP_GETSOCKNAME,
};
/*

View File

@@ -132,6 +132,26 @@ static int io_uring_cmd_timestamp(struct socket *sock,
return -EAGAIN;
}
static int io_uring_cmd_getsockname(struct socket *sock,
struct io_uring_cmd *cmd,
unsigned int issue_flags)
{
const struct io_uring_sqe *sqe = cmd->sqe;
struct sockaddr __user *uaddr;
unsigned int peer;
int __user *ulen;
if (sqe->ioprio || sqe->__pad1 || sqe->len || sqe->rw_flags)
return -EINVAL;
uaddr = u64_to_user_ptr(READ_ONCE(sqe->addr));
ulen = u64_to_user_ptr(sqe->addr3);
peer = READ_ONCE(sqe->optlen);
if (peer > 1)
return -EINVAL;
return do_getsockname(sock, peer, uaddr, ulen);
}
int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags)
{
struct socket *sock = cmd->file->private_data;
@@ -159,6 +179,8 @@ int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags)
return io_uring_cmd_setsockopt(sock, cmd, issue_flags);
case SOCKET_URING_OP_TX_TIMESTAMP:
return io_uring_cmd_timestamp(sock, cmd, issue_flags);
case SOCKET_URING_OP_GETSOCKNAME:
return io_uring_cmd_getsockname(sock, cmd, issue_flags);
default:
return -EOPNOTSUPP;
}