summaryrefslogtreecommitdiff
path: root/net/unix/af_unix.c
diff options
context:
space:
mode:
authorSimon Horman <horms+renesas@verge.net.au>2015-11-24 06:00:02 +0300
committerSimon Horman <horms+renesas@verge.net.au>2015-11-24 06:00:02 +0300
commit998f468f34f41905051556a9897dbc204b1b75b4 (patch)
tree75e402d58ccdcf516daf6a0fa8f54e33cf841787 /net/unix/af_unix.c
parentd537543b3948bc3bc9dede248fa455493e055457 (diff)
parent8005c49d9aea74d382f474ce11afbbc7d7130bec (diff)
downloadlinux-998f468f34f41905051556a9897dbc204b1b75b4.tar.xz
Merge tag 'v4.4-rc1' into HEAD
Linux 4.4-rc1
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r--net/unix/af_unix.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 03ee4d359f6a..aaa0b58d6aba 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -326,9 +326,10 @@ found:
return s;
}
-static inline int unix_writable(struct sock *sk)
+static int unix_writable(const struct sock *sk)
{
- return (atomic_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
+ return sk->sk_state != TCP_LISTEN &&
+ (atomic_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
}
static void unix_write_space(struct sock *sk)
@@ -2064,6 +2065,11 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state)
goto out;
}
+ if (flags & MSG_PEEK)
+ skip = sk_peek_offset(sk, flags);
+ else
+ skip = 0;
+
do {
int chunk;
struct sk_buff *skb, *last;
@@ -2112,7 +2118,6 @@ unlock:
break;
}
- skip = sk_peek_offset(sk, flags);
while (skip >= unix_skb_len(skb)) {
skip -= unix_skb_len(skb);
last = skb;
@@ -2181,6 +2186,17 @@ unlock:
sk_peek_offset_fwd(sk, chunk);
+ if (UNIXCB(skb).fp)
+ break;
+
+ skip = 0;
+ last = skb;
+ last_len = skb->len;
+ unix_state_lock(sk);
+ skb = skb_peek_next(skb, &sk->sk_receive_queue);
+ if (skb)
+ goto again;
+ unix_state_unlock(sk);
break;
}
} while (size);