From 246d7701e4dc08c9f833a66fa9e61a3803fa360c Mon Sep 17 00:00:00 2001 From: Andrew Wood Date: Mon, 1 Jun 2026 21:36:38 +0100 Subject: [PATCH] Cap the amount passed to splice() and copy_file_range() to a specific value, don't just pass SIZE_MAX, since that value can cause errors, making the transfer fall back to read()/write(). --- src/include/pv-internal.h | 2 ++ src/pv/transfer.c | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/include/pv-internal.h b/src/include/pv-internal.h index a968569..4dcab94 100644 --- a/src/include/pv-internal.h +++ b/src/include/pv-internal.h @@ -31,6 +31,8 @@ extern "C" { #define BUFFER_SIZE_MAX (size_t) 524288 /* max auto transfer buffer size */ #define MAX_READ_AT_ONCE (size_t) 524288 /* max to read() in one go */ #define MAX_WRITE_AT_ONCE (size_t) 524288 /* max to write() in one go */ +#define MAX_SPLICE_AT_ONCE 1048576 /* max to splice() in one go */ +#define MAX_CFR_AT_ONCE 1073741824 /* max to copy_file_range() in one go */ #define TRANSFER_READ_TIMEOUT 0.09L /* seconds to time reads out at */ #define TRANSFER_WRITE_TIMEOUT 0.9L /* seconds to time writes out at */ #define MAX_LINE_POSITIONS 100000 /* number of lines to remember positions of */ diff --git a/src/pv/transfer.c b/src/pv/transfer.c index 6c7b769..7781358 100644 --- a/src/pv/transfer.c +++ b/src/pv/transfer.c @@ -408,7 +408,7 @@ static ssize_t pv__transfer__splice_via_intermediate(pvstate_t state, int input_ * The number of bytes spliced is capped to "max_to_read", or if * "max_to_write" is greater than zero and less than "max_to_read", capped * to "max_to_write". A "max_to_read" of less than zero indicates no - * maximum. + * maximum, in which case up to MAX_SPLICE_AT_ONCE bytes are spliced. * * If state->control.rate_limit_active is true and "max_to_write" is zero, * performs no action and returns zero. Since this looks the same as EOF, @@ -463,7 +463,7 @@ static ssize_t pv__transfer__splice_repeated(pvstate_t state, int input_fd, int * it might appear to be 0. */ /*@-unrecog@ */ - bytes_to_splice = SIZE_MAX; + bytes_to_splice = MAX_SPLICE_AT_ONCE; if ((max_to_read >= 0) && ((unsigned long long) max_to_read <= (unsigned long long) SIZE_MAX)) { bytes_to_splice = (size_t) max_to_read; } @@ -618,7 +618,7 @@ static ssize_t pv__transfer__splice_repeated(pvstate_t state, int input_fd, int * The number of bytes copied is capped to "max_to_read", or if * "max_to_write" is greater than zero and less than "max_to_read", capped * to "max_to_write". A "max_to_read" of less than zero indicates no - * maximum. + * maximum, in which case up to MAX_CFR_AT_ONCE bytes are copied. * * If state->control.rate_limit_active is true and "max_to_write" is zero, * performs no action and returns zero. Since this looks the same as EOF, @@ -673,7 +673,7 @@ static ssize_t pv__transfer__copy_file_range_repeated(pvstate_t state, int input * it might appear to be 0. */ /*@-unrecog@ */ - bytes_to_copy = SIZE_MAX; + bytes_to_copy = MAX_CFR_AT_ONCE; if ((max_to_read >= 0) && ((unsigned long) max_to_read <= (unsigned long) SIZE_MAX)) { bytes_to_copy = (size_t) max_to_read; }