diff options
| -rw-r--r-- | net/ipv4/tcp.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 5f173dccd1e..2aa69c8ae60 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -1428,12 +1428,12 @@ static void tcp_service_net_dma(struct sock *sk, bool wait) | |||
| 1428 | } | 1428 | } |
| 1429 | #endif | 1429 | #endif |
| 1430 | 1430 | ||
| 1431 | static inline struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) | 1431 | static struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) |
| 1432 | { | 1432 | { |
| 1433 | struct sk_buff *skb; | 1433 | struct sk_buff *skb; |
| 1434 | u32 offset; | 1434 | u32 offset; |
| 1435 | 1435 | ||
| 1436 | skb_queue_walk(&sk->sk_receive_queue, skb) { | 1436 | while ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) { |
| 1437 | offset = seq - TCP_SKB_CB(skb)->seq; | 1437 | offset = seq - TCP_SKB_CB(skb)->seq; |
| 1438 | if (tcp_hdr(skb)->syn) | 1438 | if (tcp_hdr(skb)->syn) |
| 1439 | offset--; | 1439 | offset--; |
| @@ -1441,6 +1441,11 @@ static inline struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) | |||
| 1441 | *off = offset; | 1441 | *off = offset; |
| 1442 | return skb; | 1442 | return skb; |
| 1443 | } | 1443 | } |
| 1444 | /* This looks weird, but this can happen if TCP collapsing | ||
| 1445 | * splitted a fat GRO packet, while we released socket lock | ||
| 1446 | * in skb_splice_bits() | ||
| 1447 | */ | ||
| 1448 | sk_eat_skb(sk, skb, false); | ||
| 1444 | } | 1449 | } |
| 1445 | return NULL; | 1450 | return NULL; |
| 1446 | } | 1451 | } |
| @@ -1520,8 +1525,10 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, | |||
| 1520 | tcp_rcv_space_adjust(sk); | 1525 | tcp_rcv_space_adjust(sk); |
| 1521 | 1526 | ||
| 1522 | /* Clean up data we have read: This will do ACK frames. */ | 1527 | /* Clean up data we have read: This will do ACK frames. */ |
| 1523 | if (copied > 0) | 1528 | if (copied > 0) { |
| 1529 | tcp_recv_skb(sk, seq, &offset); | ||
| 1524 | tcp_cleanup_rbuf(sk, copied); | 1530 | tcp_cleanup_rbuf(sk, copied); |
| 1531 | } | ||
| 1525 | return copied; | 1532 | return copied; |
| 1526 | } | 1533 | } |
| 1527 | EXPORT_SYMBOL(tcp_read_sock); | 1534 | EXPORT_SYMBOL(tcp_read_sock); |
