Commit 5d24321e authored by Gabriel Krisman Bertazi's avatar Gabriel Krisman Bertazi Committed by Jens Axboe
Browse files

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: default avatarGabriel Krisman Bertazi <krisman@suse.de>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent d73c1677
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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,
};

/*
+22 −0
Original line number Diff line number Diff line
@@ -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;
	}