diff options
Diffstat (limited to 'net/ipv4/tcp.c')
| -rw-r--r-- | net/ipv4/tcp.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index f88653138621..fc54a48fde1e 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -1227,7 +1227,14 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, | |||
| 1227 | copied += used; | 1227 | copied += used; |
| 1228 | offset += used; | 1228 | offset += used; |
| 1229 | } | 1229 | } |
| 1230 | if (offset != skb->len) | 1230 | /* |
| 1231 | * If recv_actor drops the lock (e.g. TCP splice | ||
| 1232 | * receive) the skb pointer might be invalid when | ||
| 1233 | * getting here: tcp_collapse might have deleted it | ||
| 1234 | * while aggregating skbs from the socket queue. | ||
| 1235 | */ | ||
| 1236 | skb = tcp_recv_skb(sk, seq-1, &offset); | ||
| 1237 | if (!skb || (offset+1 != skb->len)) | ||
| 1231 | break; | 1238 | break; |
| 1232 | } | 1239 | } |
| 1233 | if (tcp_hdr(skb)->fin) { | 1240 | if (tcp_hdr(skb)->fin) { |
| @@ -2105,12 +2112,15 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
| 2105 | break; | 2112 | break; |
| 2106 | 2113 | ||
| 2107 | case TCP_DEFER_ACCEPT: | 2114 | case TCP_DEFER_ACCEPT: |
| 2108 | if (val < 0) { | 2115 | icsk->icsk_accept_queue.rskq_defer_accept = 0; |
| 2109 | err = -EINVAL; | 2116 | if (val > 0) { |
| 2110 | } else { | 2117 | /* Translate value in seconds to number of |
| 2111 | if (val > MAX_TCP_ACCEPT_DEFERRED) | 2118 | * retransmits */ |
| 2112 | val = MAX_TCP_ACCEPT_DEFERRED; | 2119 | while (icsk->icsk_accept_queue.rskq_defer_accept < 32 && |
| 2113 | icsk->icsk_accept_queue.rskq_defer_accept = val; | 2120 | val > ((TCP_TIMEOUT_INIT / HZ) << |
| 2121 | icsk->icsk_accept_queue.rskq_defer_accept)) | ||
| 2122 | icsk->icsk_accept_queue.rskq_defer_accept++; | ||
| 2123 | icsk->icsk_accept_queue.rskq_defer_accept++; | ||
| 2114 | } | 2124 | } |
| 2115 | break; | 2125 | break; |
| 2116 | 2126 | ||
| @@ -2292,7 +2302,8 @@ static int do_tcp_getsockopt(struct sock *sk, int level, | |||
| 2292 | val = (val ? : sysctl_tcp_fin_timeout) / HZ; | 2302 | val = (val ? : sysctl_tcp_fin_timeout) / HZ; |
| 2293 | break; | 2303 | break; |
| 2294 | case TCP_DEFER_ACCEPT: | 2304 | case TCP_DEFER_ACCEPT: |
| 2295 | val = icsk->icsk_accept_queue.rskq_defer_accept; | 2305 | val = !icsk->icsk_accept_queue.rskq_defer_accept ? 0 : |
| 2306 | ((TCP_TIMEOUT_INIT / HZ) << (icsk->icsk_accept_queue.rskq_defer_accept - 1)); | ||
| 2296 | break; | 2307 | break; |
| 2297 | case TCP_WINDOW_CLAMP: | 2308 | case TCP_WINDOW_CLAMP: |
| 2298 | val = tp->window_clamp; | 2309 | val = tp->window_clamp; |
