aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix/af_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r--net/unix/af_unix.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 85d3bb7490aa..3d9481de031f 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -530,6 +530,16 @@ static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *,
530static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *, 530static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *,
531 struct msghdr *, size_t, int); 531 struct msghdr *, size_t, int);
532 532
533static void unix_set_peek_off(struct sock *sk, int val)
534{
535 struct unix_sock *u = unix_sk(sk);
536
537 mutex_lock(&u->readlock);
538 sk->sk_peek_off = val;
539 mutex_unlock(&u->readlock);
540}
541
542
533static const struct proto_ops unix_stream_ops = { 543static const struct proto_ops unix_stream_ops = {
534 .family = PF_UNIX, 544 .family = PF_UNIX,
535 .owner = THIS_MODULE, 545 .owner = THIS_MODULE,
@@ -570,6 +580,7 @@ static const struct proto_ops unix_dgram_ops = {
570 .recvmsg = unix_dgram_recvmsg, 580 .recvmsg = unix_dgram_recvmsg,
571 .mmap = sock_no_mmap, 581 .mmap = sock_no_mmap,
572 .sendpage = sock_no_sendpage, 582 .sendpage = sock_no_sendpage,
583 .set_peek_off = unix_set_peek_off,
573}; 584};
574 585
575static const struct proto_ops unix_seqpacket_ops = { 586static const struct proto_ops unix_seqpacket_ops = {
@@ -591,6 +602,7 @@ static const struct proto_ops unix_seqpacket_ops = {
591 .recvmsg = unix_seqpacket_recvmsg, 602 .recvmsg = unix_seqpacket_recvmsg,
592 .mmap = sock_no_mmap, 603 .mmap = sock_no_mmap,
593 .sendpage = sock_no_sendpage, 604 .sendpage = sock_no_sendpage,
605 .set_peek_off = unix_set_peek_off,
594}; 606};
595 607
596static struct proto unix_proto = { 608static struct proto unix_proto = {
@@ -1756,6 +1768,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1756 int noblock = flags & MSG_DONTWAIT; 1768 int noblock = flags & MSG_DONTWAIT;
1757 struct sk_buff *skb; 1769 struct sk_buff *skb;
1758 int err; 1770 int err;
1771 int peeked, skip;
1759 1772
1760 err = -EOPNOTSUPP; 1773 err = -EOPNOTSUPP;
1761 if (flags&MSG_OOB) 1774 if (flags&MSG_OOB)
@@ -1769,7 +1782,9 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1769 goto out; 1782 goto out;
1770 } 1783 }
1771 1784
1772 skb = skb_recv_datagram(sk, flags, noblock, &err); 1785 skip = sk_peek_offset(sk, flags);
1786
1787 skb = __skb_recv_datagram(sk, flags, &peeked, &skip, &err);
1773 if (!skb) { 1788 if (!skb) {
1774 unix_state_lock(sk); 1789 unix_state_lock(sk);
1775 /* Signal EOF on disconnected non-blocking SEQPACKET socket. */ 1790 /* Signal EOF on disconnected non-blocking SEQPACKET socket. */
@@ -1786,12 +1801,12 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1786 if (msg->msg_name) 1801 if (msg->msg_name)
1787 unix_copy_addr(msg, skb->sk); 1802 unix_copy_addr(msg, skb->sk);
1788 1803
1789 if (size > skb->len) 1804 if (size > skb->len - skip)
1790 size = skb->len; 1805 size = skb->len - skip;
1791 else if (size < skb->len) 1806 else if (size < skb->len - skip)
1792 msg->msg_flags |= MSG_TRUNC; 1807 msg->msg_flags |= MSG_TRUNC;
1793 1808
1794 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size); 1809 err = skb_copy_datagram_iovec(skb, skip, msg->msg_iov, size);
1795 if (err) 1810 if (err)
1796 goto out_free; 1811 goto out_free;
1797 1812
@@ -1808,6 +1823,8 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1808 if (!(flags & MSG_PEEK)) { 1823 if (!(flags & MSG_PEEK)) {
1809 if (UNIXCB(skb).fp) 1824 if (UNIXCB(skb).fp)
1810 unix_detach_fds(siocb->scm, skb); 1825 unix_detach_fds(siocb->scm, skb);
1826
1827 sk_peek_offset_bwd(sk, skb->len);
1811 } else { 1828 } else {
1812 /* It is questionable: on PEEK we could: 1829 /* It is questionable: on PEEK we could:
1813 - do not return fds - good, but too simple 8) 1830 - do not return fds - good, but too simple 8)
@@ -1821,6 +1838,9 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1821 clearly however! 1838 clearly however!
1822 1839
1823 */ 1840 */
1841
1842 sk_peek_offset_fwd(sk, size);
1843
1824 if (UNIXCB(skb).fp) 1844 if (UNIXCB(skb).fp)
1825 siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp); 1845 siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp);
1826 } 1846 }