forked from mirrors/linux
		
	tcp: Introduce tcp_read_skb()
This patch inroduces tcp_read_skb() based on tcp_read_sock(), a preparation for the next patch which actually introduces a new sock ops. TCP is special here, because it has tcp_read_sock() which is mainly used by splice(). tcp_read_sock() supports partial read and arbitrary offset, neither of them is needed for sockmap. Signed-off-by: Cong Wang <cong.wang@bytedance.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Reviewed-by: Eric Dumazet <edumazet@google.com> Reviewed-by: John Fastabend <john.fastabend@gmail.com> Link: https://lore.kernel.org/bpf/20220615162014.89193-2-xiyou.wangcong@gmail.com
This commit is contained in:
		
							parent
							
								
									4336487e30
								
							
						
					
					
						commit
						04919bed94
					
				
					 2 changed files with 49 additions and 0 deletions
				
			
		|  | @ -672,6 +672,8 @@ void tcp_get_info(struct sock *, struct tcp_info *); | |||
| /* Read 'sendfile()'-style from a TCP socket */ | ||||
| int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, | ||||
| 		  sk_read_actor_t recv_actor); | ||||
| int tcp_read_skb(struct sock *sk, read_descriptor_t *desc, | ||||
| 		 sk_read_actor_t recv_actor); | ||||
| 
 | ||||
| void tcp_initialize_rcv_mss(struct sock *sk); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1734,6 +1734,53 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, | |||
| } | ||||
| EXPORT_SYMBOL(tcp_read_sock); | ||||
| 
 | ||||
| int tcp_read_skb(struct sock *sk, read_descriptor_t *desc, | ||||
| 		 sk_read_actor_t recv_actor) | ||||
| { | ||||
| 	struct tcp_sock *tp = tcp_sk(sk); | ||||
| 	u32 seq = tp->copied_seq; | ||||
| 	struct sk_buff *skb; | ||||
| 	int copied = 0; | ||||
| 	u32 offset; | ||||
| 
 | ||||
| 	if (sk->sk_state == TCP_LISTEN) | ||||
| 		return -ENOTCONN; | ||||
| 
 | ||||
| 	while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) { | ||||
| 		int used; | ||||
| 
 | ||||
| 		__skb_unlink(skb, &sk->sk_receive_queue); | ||||
| 		used = recv_actor(desc, skb, 0, skb->len); | ||||
| 		if (used <= 0) { | ||||
| 			if (!copied) | ||||
| 				copied = used; | ||||
| 			break; | ||||
| 		} | ||||
| 		seq += used; | ||||
| 		copied += used; | ||||
| 
 | ||||
| 		if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) { | ||||
| 			consume_skb(skb); | ||||
| 			++seq; | ||||
| 			break; | ||||
| 		} | ||||
| 		consume_skb(skb); | ||||
| 		if (!desc->count) | ||||
| 			break; | ||||
| 		WRITE_ONCE(tp->copied_seq, seq); | ||||
| 	} | ||||
| 	WRITE_ONCE(tp->copied_seq, seq); | ||||
| 
 | ||||
| 	tcp_rcv_space_adjust(sk); | ||||
| 
 | ||||
| 	/* Clean up data we have read: This will do ACK frames. */ | ||||
| 	if (copied > 0) | ||||
| 		tcp_cleanup_rbuf(sk, copied); | ||||
| 
 | ||||
| 	return copied; | ||||
| } | ||||
| EXPORT_SYMBOL(tcp_read_skb); | ||||
| 
 | ||||
| int tcp_peek_len(struct socket *sock) | ||||
| { | ||||
| 	return tcp_inq(sock->sk); | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Cong Wang
						Cong Wang