From: Lennart Poettering Date: Fri, 24 May 2024 10:17:00 +0000 (+0200) Subject: copy: when a progress callback is provided, never copy more than 1M per iteration X-Git-Tag: v257-rc1~1148^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0de442ac3115ce1719b32374f819d5c4ae4354db;p=thirdparty%2Fsystemd.git copy: when a progress callback is provided, never copy more than 1M per iteration Otherwise if we have to fill GB of data we might never call into the callback, hence put some limit on how much to copy per iteration. --- diff --git a/src/shared/copy.c b/src/shared/copy.c index 6d984894f97..def8bd1933e 100644 --- a/src/shared/copy.c +++ b/src/shared/copy.c @@ -41,8 +41,13 @@ #include "user-util.h" #include "xattr-util.h" +/* If we copy via a userspace buffer, size it to 16K */ #define COPY_BUFFER_SIZE (16U*1024U) +/* If a byte progress function is specified during copying, never try to copy more than 1M, so that we can + * reasonably call the progress function still */ +#define PROGRESS_STEP_SIZE (1U*U64_MB) + /* A safety net for descending recursively into file system trees to copy. On Linux PATH_MAX is 4096, which means the * deepest valid path one can build is around 2048, which we hence use as a safety net here, to not spin endlessly in * case of bind mount cycles and suchlike. */ @@ -284,6 +289,9 @@ int copy_bytes_full( if (max_bytes != UINT64_MAX && m > max_bytes) m = max_bytes; + if (progress && m > PROGRESS_STEP_SIZE) + m = PROGRESS_STEP_SIZE; + if (copy_flags & COPY_HOLES) { off_t c, e;