git: a0102dee34bc - main - sockets: in sousrsend() pass down the error to aio(4)

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Wed, 01 Feb 2023 21:08:36 UTC
The branch main has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=a0102dee34bce26b4a178bcc35bd153c3361fd97

commit a0102dee34bce26b4a178bcc35bd153c3361fd97
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2023-02-01 21:03:10 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2023-02-01 21:03:10 +0000

    sockets: in sousrsend() pass down the error to aio(4)
    
    This somewhat undermines the initial goal of sousrsend() to have all
    the special error handling for a write on a socket in a single place.
    The aio(4) needs to see EWOULDBLOCK to re-schedule the job.  Because
    aio(4) handles return from soreceive() and sousrsend() with the same
    code, we can't check for (error == 0 && done < job_nbytes).  Keeping
    this exclusion for aio(4) seems a lesser evil.
    
    Fixes:  7a2c93b86ef75390a60a4b4d6e3911b36221dfbe
---
 sys/kern/uipc_socket.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index b7e43d496d1d..9b7f63a81617 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -1861,8 +1861,15 @@ sousrsend(struct socket *so, struct sockaddr *addr, struct uio *uio,
 	    td);
 	CURVNET_RESTORE();
 	if (error != 0) {
+		/*
+		 * Clear transient errors for stream protocols if they made
+		 * some progress.  Make exclusion for aio(4) that would
+		 * schedule a new write in case of EWOULDBLOCK and clear
+		 * error itself.  See soaio_process_job().
+		 */
 		if (uio->uio_resid != len &&
 		    (so->so_proto->pr_flags & PR_ATOMIC) == 0 &&
+		    userproc == NULL &&
 		    (error == ERESTART || error == EINTR ||
 		    error == EWOULDBLOCK))
 			error = 0;