@@ -1567,17 +1567,11 @@ static int tcp_peek_sndq(struct sock *sk, struct msghdr *msg, int len)
15671567 * calculation of whether or not we must ACK for the sake of
15681568 * a window update.
15691569 */
1570- void tcp_cleanup_rbuf (struct sock * sk , int copied )
1570+ static void __tcp_cleanup_rbuf (struct sock * sk , int copied )
15711571{
15721572 struct tcp_sock * tp = tcp_sk (sk );
15731573 bool time_to_ack = false;
15741574
1575- struct sk_buff * skb = skb_peek (& sk -> sk_receive_queue );
1576-
1577- WARN (skb && !before (tp -> copied_seq , TCP_SKB_CB (skb )-> end_seq ),
1578- "cleanup rbuf bug: copied %X seq %X rcvnxt %X\n" ,
1579- tp -> copied_seq , TCP_SKB_CB (skb )-> end_seq , tp -> rcv_nxt );
1580-
15811575 if (inet_csk_ack_scheduled (sk )) {
15821576 const struct inet_connection_sock * icsk = inet_csk (sk );
15831577
@@ -1623,6 +1617,17 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied)
16231617 tcp_send_ack (sk );
16241618}
16251619
1620+ void tcp_cleanup_rbuf (struct sock * sk , int copied )
1621+ {
1622+ struct sk_buff * skb = skb_peek (& sk -> sk_receive_queue );
1623+ struct tcp_sock * tp = tcp_sk (sk );
1624+
1625+ WARN (skb && !before (tp -> copied_seq , TCP_SKB_CB (skb )-> end_seq ),
1626+ "cleanup rbuf bug: copied %X seq %X rcvnxt %X\n" ,
1627+ tp -> copied_seq , TCP_SKB_CB (skb )-> end_seq , tp -> rcv_nxt );
1628+ __tcp_cleanup_rbuf (sk , copied );
1629+ }
1630+
16261631static void tcp_eat_recv_skb (struct sock * sk , struct sk_buff * skb )
16271632{
16281633 __skb_unlink (skb , & sk -> sk_receive_queue );
@@ -1756,34 +1761,26 @@ int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor)
17561761 if (sk -> sk_state == TCP_LISTEN )
17571762 return - ENOTCONN ;
17581763
1759- while ((skb = tcp_recv_skb (sk , seq , & offset )) != NULL ) {
1760- int used ;
1761-
1762- __skb_unlink (skb , & sk -> sk_receive_queue );
1763- used = recv_actor (sk , skb );
1764- if (used <= 0 ) {
1765- if (!copied )
1766- copied = used ;
1767- break ;
1768- }
1769- seq += used ;
1770- copied += used ;
1764+ skb = tcp_recv_skb (sk , seq , & offset );
1765+ if (!skb )
1766+ return 0 ;
17711767
1772- if (TCP_SKB_CB (skb )-> tcp_flags & TCPHDR_FIN ) {
1773- consume_skb (skb );
1768+ __skb_unlink (skb , & sk -> sk_receive_queue );
1769+ WARN_ON (!skb_set_owner_sk_safe (skb , sk ));
1770+ copied = recv_actor (sk , skb );
1771+ if (copied >= 0 ) {
1772+ seq += copied ;
1773+ if (TCP_SKB_CB (skb )-> tcp_flags & TCPHDR_FIN )
17741774 ++ seq ;
1775- break ;
1776- }
1777- consume_skb (skb );
1778- break ;
17791775 }
1776+ consume_skb (skb );
17801777 WRITE_ONCE (tp -> copied_seq , seq );
17811778
17821779 tcp_rcv_space_adjust (sk );
17831780
17841781 /* Clean up data we have read: This will do ACK frames. */
17851782 if (copied > 0 )
1786- tcp_cleanup_rbuf (sk , copied );
1783+ __tcp_cleanup_rbuf (sk , copied );
17871784
17881785 return copied ;
17891786}
0 commit comments