Commit 29df44fa authored by Cong Wang's avatar Cong Wang Committed by Alexei Starovoitov
Browse files

af_unix: Implement ->read_sock() for sockmap



Implement ->read_sock() for AF_UNIX datagram socket, it is
pretty much similar to udp_read_sock().

Signed-off-by: default avatarCong Wang <cong.wang@bytedance.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20210704190252.11866-4-xiyou.wangcong@gmail.com
parent 0c48eefa
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -669,6 +669,8 @@ static ssize_t unix_stream_splice_read(struct socket *, loff_t *ppos,
				       unsigned int flags);
static int unix_dgram_sendmsg(struct socket *, struct msghdr *, size_t);
static int unix_dgram_recvmsg(struct socket *, struct msghdr *, size_t, int);
static int unix_read_sock(struct sock *sk, read_descriptor_t *desc,
			  sk_read_actor_t recv_actor);
static int unix_dgram_connect(struct socket *, struct sockaddr *,
			      int, int);
static int unix_seqpacket_sendmsg(struct socket *, struct msghdr *, size_t);
@@ -746,6 +748,7 @@ static const struct proto_ops unix_dgram_ops = {
	.listen =	sock_no_listen,
	.shutdown =	unix_shutdown,
	.sendmsg =	unix_dgram_sendmsg,
	.read_sock =	unix_read_sock,
	.recvmsg =	unix_dgram_recvmsg,
	.mmap =		sock_no_mmap,
	.sendpage =	sock_no_sendpage,
@@ -2188,6 +2191,40 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
	return err;
}

static int unix_read_sock(struct sock *sk, read_descriptor_t *desc,
			  sk_read_actor_t recv_actor)
{
	int copied = 0;

	while (1) {
		struct unix_sock *u = unix_sk(sk);
		struct sk_buff *skb;
		int used, err;

		mutex_lock(&u->iolock);
		skb = skb_recv_datagram(sk, 0, 1, &err);
		mutex_unlock(&u->iolock);
		if (!skb)
			return err;

		used = recv_actor(desc, skb, 0, skb->len);
		if (used <= 0) {
			if (!copied)
				copied = used;
			kfree_skb(skb);
			break;
		} else if (used <= skb->len) {
			copied += used;
		}

		kfree_skb(skb);
		if (!desc->count)
			break;
	}

	return copied;
}

/*
 *	Sleep until more data has arrived. But check for races..
 */