diff options
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r-- | net/ipv4/tcp_output.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 1b326ed46f7b..4fcc9a768849 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -3055,7 +3055,7 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn) | |||
3055 | { | 3055 | { |
3056 | struct tcp_sock *tp = tcp_sk(sk); | 3056 | struct tcp_sock *tp = tcp_sk(sk); |
3057 | struct tcp_fastopen_request *fo = tp->fastopen_req; | 3057 | struct tcp_fastopen_request *fo = tp->fastopen_req; |
3058 | int syn_loss = 0, space, err = 0; | 3058 | int syn_loss = 0, space, err = 0, copied; |
3059 | unsigned long last_syn_loss = 0; | 3059 | unsigned long last_syn_loss = 0; |
3060 | struct sk_buff *syn_data; | 3060 | struct sk_buff *syn_data; |
3061 | 3061 | ||
@@ -3093,11 +3093,16 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn) | |||
3093 | goto fallback; | 3093 | goto fallback; |
3094 | syn_data->ip_summed = CHECKSUM_PARTIAL; | 3094 | syn_data->ip_summed = CHECKSUM_PARTIAL; |
3095 | memcpy(syn_data->cb, syn->cb, sizeof(syn->cb)); | 3095 | memcpy(syn_data->cb, syn->cb, sizeof(syn->cb)); |
3096 | if (unlikely(memcpy_fromiovecend(skb_put(syn_data, space), | 3096 | copied = copy_from_iter(skb_put(syn_data, space), space, |
3097 | fo->data->msg_iter.iov, 0, space))) { | 3097 | &fo->data->msg_iter); |
3098 | if (unlikely(!copied)) { | ||
3098 | kfree_skb(syn_data); | 3099 | kfree_skb(syn_data); |
3099 | goto fallback; | 3100 | goto fallback; |
3100 | } | 3101 | } |
3102 | if (copied != space) { | ||
3103 | skb_trim(syn_data, copied); | ||
3104 | space = copied; | ||
3105 | } | ||
3101 | 3106 | ||
3102 | /* No more data pending in inet_wait_for_connect() */ | 3107 | /* No more data pending in inet_wait_for_connect() */ |
3103 | if (space == fo->size) | 3108 | if (space == fo->size) |