aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix
diff options
context:
space:
mode:
Diffstat (limited to 'net/unix')
-rw-r--r--net/unix/af_unix.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 9efe01113c5c..826e09938bff 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1858,10 +1858,10 @@ out:
1858} 1858}
1859 1859
1860/* 1860/*
1861 * Sleep until data has arrive. But check for races.. 1861 * Sleep until more data has arrived. But check for races..
1862 */ 1862 */
1863 1863static long unix_stream_data_wait(struct sock *sk, long timeo,
1864static long unix_stream_data_wait(struct sock *sk, long timeo) 1864 struct sk_buff *last)
1865{ 1865{
1866 DEFINE_WAIT(wait); 1866 DEFINE_WAIT(wait);
1867 1867
@@ -1870,7 +1870,7 @@ static long unix_stream_data_wait(struct sock *sk, long timeo)
1870 for (;;) { 1870 for (;;) {
1871 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 1871 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1872 1872
1873 if (!skb_queue_empty(&sk->sk_receive_queue) || 1873 if (skb_peek_tail(&sk->sk_receive_queue) != last ||
1874 sk->sk_err || 1874 sk->sk_err ||
1875 (sk->sk_shutdown & RCV_SHUTDOWN) || 1875 (sk->sk_shutdown & RCV_SHUTDOWN) ||
1876 signal_pending(current) || 1876 signal_pending(current) ||
@@ -1889,8 +1889,6 @@ static long unix_stream_data_wait(struct sock *sk, long timeo)
1889 return timeo; 1889 return timeo;
1890} 1890}
1891 1891
1892
1893
1894static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, 1892static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1895 struct msghdr *msg, size_t size, 1893 struct msghdr *msg, size_t size,
1896 int flags) 1894 int flags)
@@ -1935,14 +1933,12 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1935 goto out; 1933 goto out;
1936 } 1934 }
1937 1935
1938 skip = sk_peek_offset(sk, flags);
1939
1940 do { 1936 do {
1941 int chunk; 1937 int chunk;
1942 struct sk_buff *skb; 1938 struct sk_buff *skb, *last;
1943 1939
1944 unix_state_lock(sk); 1940 unix_state_lock(sk);
1945 skb = skb_peek(&sk->sk_receive_queue); 1941 last = skb = skb_peek(&sk->sk_receive_queue);
1946again: 1942again:
1947 if (skb == NULL) { 1943 if (skb == NULL) {
1948 unix_sk(sk)->recursion_level = 0; 1944 unix_sk(sk)->recursion_level = 0;
@@ -1965,7 +1961,7 @@ again:
1965 break; 1961 break;
1966 mutex_unlock(&u->readlock); 1962 mutex_unlock(&u->readlock);
1967 1963
1968 timeo = unix_stream_data_wait(sk, timeo); 1964 timeo = unix_stream_data_wait(sk, timeo, last);
1969 1965
1970 if (signal_pending(current) 1966 if (signal_pending(current)
1971 || mutex_lock_interruptible(&u->readlock)) { 1967 || mutex_lock_interruptible(&u->readlock)) {
@@ -1979,10 +1975,13 @@ again:
1979 break; 1975 break;
1980 } 1976 }
1981 1977
1982 if (skip >= skb->len) { 1978 skip = sk_peek_offset(sk, flags);
1979 while (skip >= skb->len) {
1983 skip -= skb->len; 1980 skip -= skb->len;
1981 last = skb;
1984 skb = skb_peek_next(skb, &sk->sk_receive_queue); 1982 skb = skb_peek_next(skb, &sk->sk_receive_queue);
1985 goto again; 1983 if (!skb)
1984 goto again;
1986 } 1985 }
1987 1986
1988 unix_state_unlock(sk); 1987 unix_state_unlock(sk);