Skip to content

Commit d483c85

Browse files
dcuichessturo
authored andcommitted
hv_sock: Report EOF instead of -EIO for FIN
Commit f0c5827 unluckily causes a regression for the FIN packet, and the final read syscall gets an error rather than 0. Ideally, we would want to fix hvs_channel_readable_payload() so that it could return 0 in the FIN scenario, but it's not good for the hv_sock driver to use the VMBus ringbuffer's cached priv_read_index, which is internal data in the VMBus driver. Fix the regression in hv_sock by returning 0 rather than -EIO. Fixes: f0c5827 ("hv_sock: Return the readable bytes in hvs_stream_has_data()") Cc: stable@vger.kernel.org Reported-by: Ben Hillis <Ben.Hillis@microsoft.com> Reported-by: Mitchell Levy <levymitchell0@gmail.com> Signed-off-by: Dexuan Cui <decui@microsoft.com> Acked-by: Stefano Garzarella <sgarzare@redhat.com>
1 parent 7d0a66e commit d483c85

1 file changed

Lines changed: 16 additions & 4 deletions

File tree

net/vmw_vsock/hyperv_transport.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -694,17 +694,29 @@ static ssize_t hvs_stream_enqueue(struct vsock_sock *vsk, struct msghdr *msg,
694694
static s64 hvs_stream_has_data(struct vsock_sock *vsk)
695695
{
696696
struct hvsock *hvs = vsk->trans;
697-
bool need_refill;
698697
s64 ret;
699698

700699
if (hvs->recv_data_len > 0)
701700
return hvs->recv_data_len;
702701

703702
switch (hvs_channel_readable_payload(hvs->chan)) {
704703
case 1:
705-
need_refill = !hvs->recv_desc;
706-
if (!need_refill)
707-
return -EIO;
704+
if (hvs->recv_desc) {
705+
/* Here hvs->recv_data_len is 0, so hvs->recv_desc must
706+
* be NULL unless it points to the 0-byte-payload FIN
707+
* packet: see hvs_update_recv_data().
708+
*
709+
* Here all the payload has been dequeued, but
710+
* hvs_channel_readable_payload() still returns 1,
711+
* because the VMBus ringbuffer's read_index is not
712+
* updated for the FIN packet: hvs_stream_dequeue() ->
713+
* hv_pkt_iter_next() updates the cached priv_read_index
714+
* but has no opportunity to update the read_index in
715+
* hv_pkt_iter_close() as hvs_stream_has_data() returns
716+
* 0 for the FIN packet, so it won't get dequeued.
717+
*/
718+
return 0;
719+
}
708720

709721
hvs->recv_desc = hv_pkt_iter_first(hvs->chan);
710722
if (!hvs->recv_desc)

0 commit comments

Comments
 (0)