af_vsock: separate receive data loop
authorArseny Krasnov <arseny.krasnov@kaspersky.com>
Fri, 11 Jun 2021 11:10:21 +0000 (14:10 +0300)
committerDavid S. Miller <davem@davemloft.net>
Fri, 11 Jun 2021 20:32:46 +0000 (13:32 -0700)
Some code in receive data loop could be shared between SEQPACKET
and STREAM sockets, while another part is type specific, so move STREAM
specific data receive logic to '__vsock_stream_recvmsg()' dedicated
function, while checks, that will be same for both STREAM and SEQPACKET
sockets, stays in 'vsock_connectible_recvmsg()'.

Signed-off-by: Arseny Krasnov <arseny.krasnov@kaspersky.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/vmw_vsock/af_vsock.c

index 4269e80..c4f6bfa 100644 (file)
@@ -1896,65 +1896,22 @@ static int vsock_wait_data(struct sock *sk, struct wait_queue_entry *wait,
        return data;
 }
 
-static int
-vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
-                         int flags)
+static int __vsock_stream_recvmsg(struct sock *sk, struct msghdr *msg,
+                                 size_t len, int flags)
 {
-       struct sock *sk;
-       struct vsock_sock *vsk;
+       struct vsock_transport_recv_notify_data recv_data;
        const struct vsock_transport *transport;
-       int err;
-       size_t target;
+       struct vsock_sock *vsk;
        ssize_t copied;
+       size_t target;
        long timeout;
-       struct vsock_transport_recv_notify_data recv_data;
+       int err;
 
        DEFINE_WAIT(wait);
 
-       sk = sock->sk;
        vsk = vsock_sk(sk);
-       err = 0;
-
-       lock_sock(sk);
-
        transport = vsk->transport;
 
-       if (!transport || sk->sk_state != TCP_ESTABLISHED) {
-               /* Recvmsg is supposed to return 0 if a peer performs an
-                * orderly shutdown. Differentiate between that case and when a
-                * peer has not connected or a local shutdown occurred with the
-                * SOCK_DONE flag.
-                */
-               if (sock_flag(sk, SOCK_DONE))
-                       err = 0;
-               else
-                       err = -ENOTCONN;
-
-               goto out;
-       }
-
-       if (flags & MSG_OOB) {
-               err = -EOPNOTSUPP;
-               goto out;
-       }
-
-       /* We don't check peer_shutdown flag here since peer may actually shut
-        * down, but there can be data in the queue that a local socket can
-        * receive.
-        */
-       if (sk->sk_shutdown & RCV_SHUTDOWN) {
-               err = 0;
-               goto out;
-       }
-
-       /* It is valid on Linux to pass in a zero-length receive buffer.  This
-        * is not an error.  We may as well bail out now.
-        */
-       if (!len) {
-               err = 0;
-               goto out;
-       }
-
        /* We must not copy less than target bytes into the user's buffer
         * before returning successfully, so we wait for the consume queue to
         * have that much data to consume before dequeueing.  Note that this
@@ -2014,6 +1971,67 @@ vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
                err = copied;
 
 out:
+       return err;
+}
+
+static int
+vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
+                         int flags)
+{
+       struct sock *sk;
+       struct vsock_sock *vsk;
+       const struct vsock_transport *transport;
+       int err;
+
+       DEFINE_WAIT(wait);
+
+       sk = sock->sk;
+       vsk = vsock_sk(sk);
+       err = 0;
+
+       lock_sock(sk);
+
+       transport = vsk->transport;
+
+       if (!transport || sk->sk_state != TCP_ESTABLISHED) {
+               /* Recvmsg is supposed to return 0 if a peer performs an
+                * orderly shutdown. Differentiate between that case and when a
+                * peer has not connected or a local shutdown occurred with the
+                * SOCK_DONE flag.
+                */
+               if (sock_flag(sk, SOCK_DONE))
+                       err = 0;
+               else
+                       err = -ENOTCONN;
+
+               goto out;
+       }
+
+       if (flags & MSG_OOB) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       /* We don't check peer_shutdown flag here since peer may actually shut
+        * down, but there can be data in the queue that a local socket can
+        * receive.
+        */
+       if (sk->sk_shutdown & RCV_SHUTDOWN) {
+               err = 0;
+               goto out;
+       }
+
+       /* It is valid on Linux to pass in a zero-length receive buffer.  This
+        * is not an error.  We may as well bail out now.
+        */
+       if (!len) {
+               err = 0;
+               goto out;
+       }
+
+       err = __vsock_stream_recvmsg(sk, msg, len, flags);
+
+out:
        release_sock(sk);
        return err;
 }