diff options
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r-- | net/ipv4/tcp_output.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index ffc9274b2706..60111a0fc201 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -1265,7 +1265,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, | |||
1265 | * eventually). The difference is that pulled data not copied, but | 1265 | * eventually). The difference is that pulled data not copied, but |
1266 | * immediately discarded. | 1266 | * immediately discarded. |
1267 | */ | 1267 | */ |
1268 | static void __pskb_trim_head(struct sk_buff *skb, int len) | 1268 | static int __pskb_trim_head(struct sk_buff *skb, int len) |
1269 | { | 1269 | { |
1270 | struct skb_shared_info *shinfo; | 1270 | struct skb_shared_info *shinfo; |
1271 | int i, k, eat; | 1271 | int i, k, eat; |
@@ -1275,7 +1275,7 @@ static void __pskb_trim_head(struct sk_buff *skb, int len) | |||
1275 | __skb_pull(skb, eat); | 1275 | __skb_pull(skb, eat); |
1276 | len -= eat; | 1276 | len -= eat; |
1277 | if (!len) | 1277 | if (!len) |
1278 | return; | 1278 | return 0; |
1279 | } | 1279 | } |
1280 | eat = len; | 1280 | eat = len; |
1281 | k = 0; | 1281 | k = 0; |
@@ -1301,23 +1301,28 @@ static void __pskb_trim_head(struct sk_buff *skb, int len) | |||
1301 | skb_reset_tail_pointer(skb); | 1301 | skb_reset_tail_pointer(skb); |
1302 | skb->data_len -= len; | 1302 | skb->data_len -= len; |
1303 | skb->len = skb->data_len; | 1303 | skb->len = skb->data_len; |
1304 | return len; | ||
1304 | } | 1305 | } |
1305 | 1306 | ||
1306 | /* Remove acked data from a packet in the transmit queue. */ | 1307 | /* Remove acked data from a packet in the transmit queue. */ |
1307 | int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len) | 1308 | int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len) |
1308 | { | 1309 | { |
1310 | u32 delta_truesize; | ||
1311 | |||
1309 | if (skb_unclone(skb, GFP_ATOMIC)) | 1312 | if (skb_unclone(skb, GFP_ATOMIC)) |
1310 | return -ENOMEM; | 1313 | return -ENOMEM; |
1311 | 1314 | ||
1312 | __pskb_trim_head(skb, len); | 1315 | delta_truesize = __pskb_trim_head(skb, len); |
1313 | 1316 | ||
1314 | TCP_SKB_CB(skb)->seq += len; | 1317 | TCP_SKB_CB(skb)->seq += len; |
1315 | skb->ip_summed = CHECKSUM_PARTIAL; | 1318 | skb->ip_summed = CHECKSUM_PARTIAL; |
1316 | 1319 | ||
1317 | skb->truesize -= len; | 1320 | if (delta_truesize) { |
1318 | sk->sk_wmem_queued -= len; | 1321 | skb->truesize -= delta_truesize; |
1319 | sk_mem_uncharge(sk, len); | 1322 | sk->sk_wmem_queued -= delta_truesize; |
1320 | sock_set_flag(sk, SOCK_QUEUE_SHRUNK); | 1323 | sk_mem_uncharge(sk, delta_truesize); |
1324 | sock_set_flag(sk, SOCK_QUEUE_SHRUNK); | ||
1325 | } | ||
1321 | 1326 | ||
1322 | /* Any change of skb->len requires recalculation of tso factor. */ | 1327 | /* Any change of skb->len requires recalculation of tso factor. */ |
1323 | if (tcp_skb_pcount(skb) > 1) | 1328 | if (tcp_skb_pcount(skb) > 1) |