diff options
Diffstat (limited to 'net/ipv4/tcp_output.c')
| -rw-r--r-- | net/ipv4/tcp_output.c | 19 | 
1 files changed, 14 insertions, 5 deletions
| diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index cfe6ffe1c177..948ac275b9b5 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1986,6 +1986,9 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,  		tso_segs = tcp_init_tso_segs(sk, skb, mss_now);  		BUG_ON(!tso_segs); +		if (unlikely(tp->repair) && tp->repair_queue == TCP_SEND_QUEUE) +			goto repair; /* Skip network transmission */ +  		cwnd_quota = tcp_cwnd_test(tp, skb);  		if (!cwnd_quota)  			break; @@ -2026,6 +2029,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,  		if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp)))  			break; +repair:  		/* Advance the send_head.  This one is sent out.  		 * This call will increment packets_out.  		 */ @@ -2305,12 +2309,11 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to,   * state updates are done by the caller.  Returns non-zero if an   * error occurred which prevented the send.   */ -int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) +int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)  {  	struct tcp_sock *tp = tcp_sk(sk);  	struct inet_connection_sock *icsk = inet_csk(sk);  	unsigned int cur_mss; -	int err;  	/* Inconslusive MTU probe */  	if (icsk->icsk_mtup.probe_size) { @@ -2383,11 +2386,17 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)  	if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) {  		struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER,  						   GFP_ATOMIC); -		err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : -			     -ENOBUFS; +		return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : +			      -ENOBUFS;  	} else { -		err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); +		return tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);  	} +} + +int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) +{ +	struct tcp_sock *tp = tcp_sk(sk); +	int err = __tcp_retransmit_skb(sk, skb);  	if (err == 0) {  		/* Update global TCP statistics. */ |