OSDN Git Service

Merge branch 'tcp-pass-back-data-left-in-socket-after-receive' of git://git.kernel...
authorJakub Kicinski <kuba@kernel.org>
Sat, 30 Apr 2022 02:12:05 +0000 (19:12 -0700)
committerJakub Kicinski <kuba@kernel.org>
Sat, 30 Apr 2022 02:12:05 +0000 (19:12 -0700)
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1  2 
net/ipv4/tcp.c

diff --cc net/ipv4/tcp.c
@@@ -2314,9 -2335,11 +2314,11 @@@ static int tcp_recvmsg_locked(struct so
        if (sk->sk_state == TCP_LISTEN)
                goto out;
  
-       if (tp->recvmsg_inq)
+       if (tp->recvmsg_inq) {
                *cmsg_flags = TCP_CMSG_INQ;
 -      timeo = sock_rcvtimeo(sk, nonblock);
+               msg->msg_get_inq = 1;
+       }
 +      timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
  
        /* Urgent data needs to be handled specially. */
        if (flags & MSG_OOB)
@@@ -2534,10 -2558,10 +2536,10 @@@ recv_sndq
        goto out;
  }
  
 -int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
 -              int flags, int *addr_len)
 +int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
 +              int *addr_len)
  {
-       int cmsg_flags = 0, ret, inq;
+       int cmsg_flags = 0, ret;
        struct scm_timestamping_internal tss;
  
        if (unlikely(flags & MSG_ERRQUEUE))
        if (sk_can_busy_loop(sk) &&
            skb_queue_empty_lockless(&sk->sk_receive_queue) &&
            sk->sk_state == TCP_ESTABLISHED)
 -              sk_busy_loop(sk, nonblock);
 +              sk_busy_loop(sk, flags & MSG_DONTWAIT);
  
        lock_sock(sk);
 -      ret = tcp_recvmsg_locked(sk, msg, len, nonblock, flags, &tss,
 -                               &cmsg_flags);
 +      ret = tcp_recvmsg_locked(sk, msg, len, flags, &tss, &cmsg_flags);
        release_sock(sk);
 -      sk_defer_free_flush(sk);
  
-       if (cmsg_flags && ret >= 0) {
+       if ((cmsg_flags || msg->msg_get_inq) && ret >= 0) {
                if (cmsg_flags & TCP_CMSG_TS)
                        tcp_recv_timestamp(msg, sk, &tss);
-               if (cmsg_flags & TCP_CMSG_INQ) {
-                       inq = tcp_inq_hint(sk);
-                       put_cmsg(msg, SOL_TCP, TCP_CM_INQ, sizeof(inq), &inq);
+               if (msg->msg_get_inq) {
+                       msg->msg_inq = tcp_inq_hint(sk);
+                       if (cmsg_flags & TCP_CMSG_INQ)
+                               put_cmsg(msg, SOL_TCP, TCP_CM_INQ,
+                                        sizeof(msg->msg_inq), &msg->msg_inq);
                }
        }
        return ret;