]> www.infradead.org Git - nvme.git/commitdiff
af_unix: Implement ->read_sock() for sockmap
authorCong Wang <cong.wang@bytedance.com>
Sun, 4 Jul 2021 19:02:44 +0000 (12:02 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 16 Jul 2021 01:17:50 +0000 (18:17 -0700)
Implement ->read_sock() for AF_UNIX datagram socket, it is
pretty much similar to udp_read_sock().

Signed-off-by: Cong Wang <cong.wang@bytedance.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20210704190252.11866-4-xiyou.wangcong@gmail.com
net/unix/af_unix.c

index 23c92ad15c61e948c89f4896e5775b6ab070cc4c..38863468768a037393ac0a54eaa9caa19baa1605 100644 (file)
@@ -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 @@ out:
        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..
  */