vsock/virtio: add support for MSG_PEEK
This patch adds support for MSG_PEEK. In such a case, packets are not removed from the rx_queue and credit updates are not sent. Signed-off-by: Matias Ezequiel Vara Larsen <matiasevara@gmail.com> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Tested-by: Stefano Garzarella <sgarzare@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
678799194a
commit
a786ab36ae
|
@ -263,6 +263,55 @@ static int virtio_transport_send_credit_update(struct vsock_sock *vsk,
|
|||
return virtio_transport_send_pkt_info(vsk, &info);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
virtio_transport_stream_do_peek(struct vsock_sock *vsk,
|
||||
struct msghdr *msg,
|
||||
size_t len)
|
||||
{
|
||||
struct virtio_vsock_sock *vvs = vsk->trans;
|
||||
struct virtio_vsock_pkt *pkt;
|
||||
size_t bytes, total = 0, off;
|
||||
int err = -EFAULT;
|
||||
|
||||
spin_lock_bh(&vvs->rx_lock);
|
||||
|
||||
list_for_each_entry(pkt, &vvs->rx_queue, list) {
|
||||
off = pkt->off;
|
||||
|
||||
if (total == len)
|
||||
break;
|
||||
|
||||
while (total < len && off < pkt->len) {
|
||||
bytes = len - total;
|
||||
if (bytes > pkt->len - off)
|
||||
bytes = pkt->len - off;
|
||||
|
||||
/* sk_lock is held by caller so no one else can dequeue.
|
||||
* Unlock rx_lock since memcpy_to_msg() may sleep.
|
||||
*/
|
||||
spin_unlock_bh(&vvs->rx_lock);
|
||||
|
||||
err = memcpy_to_msg(msg, pkt->buf + off, bytes);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
spin_lock_bh(&vvs->rx_lock);
|
||||
|
||||
total += bytes;
|
||||
off += bytes;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_bh(&vvs->rx_lock);
|
||||
|
||||
return total;
|
||||
|
||||
out:
|
||||
if (total)
|
||||
err = total;
|
||||
return err;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
|
||||
struct msghdr *msg,
|
||||
|
@ -335,9 +384,9 @@ virtio_transport_stream_dequeue(struct vsock_sock *vsk,
|
|||
size_t len, int flags)
|
||||
{
|
||||
if (flags & MSG_PEEK)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return virtio_transport_stream_do_dequeue(vsk, msg, len);
|
||||
return virtio_transport_stream_do_peek(vsk, msg, len);
|
||||
else
|
||||
return virtio_transport_stream_do_dequeue(vsk, msg, len);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(virtio_transport_stream_dequeue);
|
||||
|
||||
|
|
Loading…
Reference in a new issue