Skip to content

Commit

Permalink
af_vsock: separate wait data loop
Browse files Browse the repository at this point in the history
Wait loop for data could be shared between SEQPACKET and STREAM
sockets, so move it to dedicated function. While moving the code
around, let's update an old comment.

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>
  • Loading branch information
Arseny Krasnov authored and David S. Miller committed Jun 11, 2021
1 parent a9e29e5 commit b3f7fd5
Showing 1 changed file with 84 additions and 72 deletions.
156 changes: 84 additions & 72 deletions net/vmw_vsock/af_vsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -1833,6 +1833,69 @@ static int vsock_connectible_sendmsg(struct socket *sock, struct msghdr *msg,
return err;
}

static int vsock_wait_data(struct sock *sk, struct wait_queue_entry *wait,
long timeout,
struct vsock_transport_recv_notify_data *recv_data,
size_t target)
{
const struct vsock_transport *transport;
struct vsock_sock *vsk;
s64 data;
int err;

vsk = vsock_sk(sk);
err = 0;
transport = vsk->transport;

while ((data = vsock_stream_has_data(vsk)) == 0) {
prepare_to_wait(sk_sleep(sk), wait, TASK_INTERRUPTIBLE);

if (sk->sk_err != 0 ||
(sk->sk_shutdown & RCV_SHUTDOWN) ||
(vsk->peer_shutdown & SEND_SHUTDOWN)) {
break;
}

/* Don't wait for non-blocking sockets. */
if (timeout == 0) {
err = -EAGAIN;
break;
}

if (recv_data) {
err = transport->notify_recv_pre_block(vsk, target, recv_data);
if (err < 0)
break;
}

release_sock(sk);
timeout = schedule_timeout(timeout);
lock_sock(sk);

if (signal_pending(current)) {
err = sock_intr_errno(timeout);
break;
} else if (timeout == 0) {
err = -EAGAIN;
break;
}
}

finish_wait(sk_sleep(sk), wait);

if (err)
return err;

/* Internal transport error when checking for available
* data. XXX This should be changed to a connection
* reset in a later change.
*/
if (data < 0)
return -ENOMEM;

return data;
}

static int
vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
int flags)
Expand Down Expand Up @@ -1912,85 +1975,34 @@ vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,


while (1) {
s64 ready;
ssize_t read;

prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
ready = vsock_stream_has_data(vsk);
err = vsock_wait_data(sk, &wait, timeout, &recv_data, target);
if (err <= 0)
break;

if (ready == 0) {
if (sk->sk_err != 0 ||
(sk->sk_shutdown & RCV_SHUTDOWN) ||
(vsk->peer_shutdown & SEND_SHUTDOWN)) {
finish_wait(sk_sleep(sk), &wait);
break;
}
/* Don't wait for non-blocking sockets. */
if (timeout == 0) {
err = -EAGAIN;
finish_wait(sk_sleep(sk), &wait);
break;
}

err = transport->notify_recv_pre_block(
vsk, target, &recv_data);
if (err < 0) {
finish_wait(sk_sleep(sk), &wait);
break;
}
release_sock(sk);
timeout = schedule_timeout(timeout);
lock_sock(sk);

if (signal_pending(current)) {
err = sock_intr_errno(timeout);
finish_wait(sk_sleep(sk), &wait);
break;
} else if (timeout == 0) {
err = -EAGAIN;
finish_wait(sk_sleep(sk), &wait);
break;
}
} else {
ssize_t read;

finish_wait(sk_sleep(sk), &wait);

if (ready < 0) {
/* Invalid queue pair content. XXX This should
* be changed to a connection reset in a later
* change.
*/

err = -ENOMEM;
goto out;
}

err = transport->notify_recv_pre_dequeue(
vsk, target, &recv_data);
if (err < 0)
break;
err = transport->notify_recv_pre_dequeue(vsk, target,
&recv_data);
if (err < 0)
break;

read = transport->stream_dequeue(
vsk, msg,
len - copied, flags);
if (read < 0) {
err = -ENOMEM;
break;
}
read = transport->stream_dequeue(vsk, msg, len - copied, flags);
if (read < 0) {
err = -ENOMEM;
break;
}

copied += read;
copied += read;

err = transport->notify_recv_post_dequeue(
vsk, target, read,
!(flags & MSG_PEEK), &recv_data);
if (err < 0)
goto out;
err = transport->notify_recv_post_dequeue(vsk, target, read,
!(flags & MSG_PEEK), &recv_data);
if (err < 0)
goto out;

if (read >= target || flags & MSG_PEEK)
break;
if (read >= target || flags & MSG_PEEK)
break;

target -= read;
}
target -= read;
}

if (sk->sk_err)
Expand Down

0 comments on commit b3f7fd5

Please sign in to comment.