diff options
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r-- | net/ipv4/tcp.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 2741953adaba..141acd92e58a 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -1694,6 +1694,13 @@ EXPORT_SYMBOL(tcp_peek_len); | |||
1694 | /* Make sure sk_rcvbuf is big enough to satisfy SO_RCVLOWAT hint */ | 1694 | /* Make sure sk_rcvbuf is big enough to satisfy SO_RCVLOWAT hint */ |
1695 | int tcp_set_rcvlowat(struct sock *sk, int val) | 1695 | int tcp_set_rcvlowat(struct sock *sk, int val) |
1696 | { | 1696 | { |
1697 | int cap; | ||
1698 | |||
1699 | if (sk->sk_userlocks & SOCK_RCVBUF_LOCK) | ||
1700 | cap = sk->sk_rcvbuf >> 1; | ||
1701 | else | ||
1702 | cap = sock_net(sk)->ipv4.sysctl_tcp_rmem[2] >> 1; | ||
1703 | val = min(val, cap); | ||
1697 | sk->sk_rcvlowat = val ? : 1; | 1704 | sk->sk_rcvlowat = val ? : 1; |
1698 | 1705 | ||
1699 | /* Check if we need to signal EPOLLIN right now */ | 1706 | /* Check if we need to signal EPOLLIN right now */ |
@@ -1702,12 +1709,7 @@ int tcp_set_rcvlowat(struct sock *sk, int val) | |||
1702 | if (sk->sk_userlocks & SOCK_RCVBUF_LOCK) | 1709 | if (sk->sk_userlocks & SOCK_RCVBUF_LOCK) |
1703 | return 0; | 1710 | return 0; |
1704 | 1711 | ||
1705 | /* val comes from user space and might be close to INT_MAX */ | ||
1706 | val <<= 1; | 1712 | val <<= 1; |
1707 | if (val < 0) | ||
1708 | val = INT_MAX; | ||
1709 | |||
1710 | val = min(val, sock_net(sk)->ipv4.sysctl_tcp_rmem[2]); | ||
1711 | if (val > sk->sk_rcvbuf) { | 1713 | if (val > sk->sk_rcvbuf) { |
1712 | sk->sk_rcvbuf = val; | 1714 | sk->sk_rcvbuf = val; |
1713 | tcp_sk(sk)->window_clamp = tcp_win_from_space(sk, val); | 1715 | tcp_sk(sk)->window_clamp = tcp_win_from_space(sk, val); |