mirror of https://gitee.com/openkylin/linux.git
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);
|
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
|
static ssize_t
|
||||||
virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
|
virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
|
||||||
struct msghdr *msg,
|
struct msghdr *msg,
|
||||||
|
@ -335,9 +384,9 @@ virtio_transport_stream_dequeue(struct vsock_sock *vsk,
|
||||||
size_t len, int flags)
|
size_t len, int flags)
|
||||||
{
|
{
|
||||||
if (flags & MSG_PEEK)
|
if (flags & MSG_PEEK)
|
||||||
return -EOPNOTSUPP;
|
return virtio_transport_stream_do_peek(vsk, msg, len);
|
||||||
|
else
|
||||||
return virtio_transport_stream_do_dequeue(vsk, msg, len);
|
return virtio_transport_stream_do_dequeue(vsk, msg, len);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(virtio_transport_stream_dequeue);
|
EXPORT_SYMBOL_GPL(virtio_transport_stream_dequeue);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue