From 11e5b5fe95093e4b7afb2df125f92d9f5b1f4132 Mon Sep 17 00:00:00 2001 From: eborisch Date: Mon, 15 Jul 2024 21:36:57 +0000 Subject: [PATCH 1/2] src/pv/transfer.c: write(2) returning 0 is not an error This is being hit easily on FreeBSD with pv sitting in a zfs send/recv pipeline. As write(2) returning 0 is not an error, handle it similar to returning -1 with EINTR or EAGAIN: wait a bit and try again. --- src/pv/transfer.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/pv/transfer.c b/src/pv/transfer.c index 01a9c5a..3480521 100644 --- a/src/pv/transfer.c +++ b/src/pv/transfer.c @@ -704,13 +704,7 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long #endif /* HAVE_SETITIMER */ } - if (0 == nwritten) { - /* - * Write returned 0 - EOF on output. - */ - *eof_out = true; - return 1; - } else if (nwritten > 0) { + if (nwritten > 0) { /* * Write returned >0 - data successfully written. */ @@ -796,14 +790,15 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long } /* - * If we reach this point, nwritten<0, so there was an error. + * If we reach this point, nwritten<0, so there may be an error. */ /* - * If a write error occurred but it was EINTR or EAGAIN, just wait a - * bit and then return zero, since this was a transient error. + * If a write error occurred but it was EINTR or EAGAIN, or write(2) + * returned 0 (not an error), just wait a bit and then return zero, + * since this was a transient error. */ - if ((EINTR == errno) || (EAGAIN == errno)) { + if ((nwritten == 0) || (EINTR == errno) || (EAGAIN == errno)) { debug("%s: %s", "transient write error - waiting briefly", strerror(errno)); (void) is_data_ready(-1, NULL, -1, NULL, 10000); return 0; From d86d8cf65a4f2bff6035955af6af0caa02ce9042 Mon Sep 17 00:00:00 2001 From: eborisch Date: Tue, 16 Jul 2024 03:57:11 +0000 Subject: [PATCH 2/2] Clarify state. --- src/pv/transfer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pv/transfer.c b/src/pv/transfer.c index 3480521..12389d5 100644 --- a/src/pv/transfer.c +++ b/src/pv/transfer.c @@ -790,7 +790,7 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long } /* - * If we reach this point, nwritten<0, so there may be an error. + * If we reach this point, nwritten<=0, so there may be an error. */ /*