Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

hv_sock: Report EOF instead of -EIO for FIN

Commit f0c5827d07cb 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: f0c5827d07cb ("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>
Link: https://patch.msgid.link/20260416191433.840637-1-decui@microsoft.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Dexuan Cui and committed by
Jakub Kicinski
f6315295 b94769eb

+16 -4
+16 -4
net/vmw_vsock/hyperv_transport.c
··· 694 694 static s64 hvs_stream_has_data(struct vsock_sock *vsk) 695 695 { 696 696 struct hvsock *hvs = vsk->trans; 697 - bool need_refill; 698 697 s64 ret; 699 698 700 699 if (hvs->recv_data_len > 0) ··· 701 702 702 703 switch (hvs_channel_readable_payload(hvs->chan)) { 703 704 case 1: 704 - need_refill = !hvs->recv_desc; 705 - if (!need_refill) 706 - return -EIO; 705 + if (hvs->recv_desc) { 706 + /* Here hvs->recv_data_len is 0, so hvs->recv_desc must 707 + * be NULL unless it points to the 0-byte-payload FIN 708 + * packet: see hvs_update_recv_data(). 709 + * 710 + * Here all the payload has been dequeued, but 711 + * hvs_channel_readable_payload() still returns 1, 712 + * because the VMBus ringbuffer's read_index is not 713 + * updated for the FIN packet: hvs_stream_dequeue() -> 714 + * hv_pkt_iter_next() updates the cached priv_read_index 715 + * but has no opportunity to update the read_index in 716 + * hv_pkt_iter_close() as hvs_stream_has_data() returns 717 + * 0 for the FIN packet, so it won't get dequeued. 718 + */ 719 + return 0; 720 + } 707 721 708 722 hvs->recv_desc = hv_pkt_iter_first(hvs->chan); 709 723 if (!hvs->recv_desc)