git: 54d8d0fe12a4 - main - xinstall: use dynamic bufsize as in cat(1) / cp(1).
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 03 Aug 2022 21:02:06 UTC
The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=54d8d0fe12a4996427923048ab4261819774fbd4 commit 54d8d0fe12a4996427923048ab4261819774fbd4 Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2022-08-03 21:00:14 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> CommitDate: 2022-08-03 21:01:13 +0000 xinstall: use dynamic bufsize as in cat(1) / cp(1). Sponsored by: Klara, Inc. --- usr.bin/xinstall/xinstall.c | 58 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c index a236838c8fd1..b0e52453ca29 100644 --- a/usr.bin/xinstall/xinstall.c +++ b/usr.bin/xinstall/xinstall.c @@ -79,6 +79,21 @@ __FBSDID("$FreeBSD$"); #include "mtree.h" +/* + * Memory strategy threshold, in pages: if physmem is larger then this, use a + * large buffer. + */ +#define PHYSPAGES_THRESHOLD (32*1024) + +/* Maximum buffer size in bytes - do not allow it to grow larger than this. */ +#define BUFSIZE_MAX (2*1024*1024) + +/* + * Small (default) buffer size in bytes. It's inefficient for this to be + * smaller than MAXPHYS. + */ +#define BUFSIZE_SMALL (MAXPHYS) + /* * We need to build xinstall during the bootstrap stage when building on a * non-FreeBSD system. Linux does not have the st_flags and st_birthtime @@ -1139,15 +1154,32 @@ compare(int from_fd, const char *from_name __unused, size_t from_len, } out: if (!done_compare) { - char buf1[MAXBSIZE]; - char buf2[MAXBSIZE]; + static char *buf, *buf1, *buf2; + static size_t bufsize; int n1, n2; + if (buf == NULL) { + /* + * Note that buf and bufsize are static. If + * malloc() fails, it will fail at the start + * and not copy only some files. + */ + if (sysconf(_SC_PHYS_PAGES) > + PHYSPAGES_THRESHOLD) + bufsize = MIN(BUFSIZE_MAX, MAXPHYS * 8); + else + bufsize = BUFSIZE_SMALL; + buf = malloc(bufsize * 2); + if (buf == NULL) + err(1, "Not enough memory"); + buf1 = buf; + buf2 = buf + bufsize; + } rv = 0; lseek(from_fd, 0, SEEK_SET); lseek(to_fd, 0, SEEK_SET); while (rv == 0) { - n1 = read(from_fd, buf1, sizeof(buf1)); + n1 = read(from_fd, buf1, bufsize); if (n1 == 0) break; /* EOF */ else if (n1 > 0) { @@ -1264,10 +1296,11 @@ static char * copy(int from_fd, const char *from_name, int to_fd, const char *to_name, off_t size) { + static char *buf = NULL; + static size_t bufsize; int nr, nw; int serrno; char *p; - char buf[MAXBSIZE]; int done_copy; DIGEST_CTX ctx; @@ -1301,7 +1334,22 @@ copy(int from_fd, const char *from_name, int to_fd, const char *to_name, done_copy = 1; } if (!done_copy) { - while ((nr = read(from_fd, buf, sizeof(buf))) > 0) { + if (buf == NULL) { + /* + * Note that buf and bufsize are static. If + * malloc() fails, it will fail at the start + * and not copy only some files. + */ + if (sysconf(_SC_PHYS_PAGES) > + PHYSPAGES_THRESHOLD) + bufsize = MIN(BUFSIZE_MAX, MAXPHYS * 8); + else + bufsize = BUFSIZE_SMALL; + buf = malloc(bufsize); + if (buf == NULL) + err(1, "Not enough memory"); + } + while ((nr = read(from_fd, buf, bufsize)) > 0) { if ((nw = write(to_fd, buf, nr)) != nr) { serrno = errno; (void)unlink(to_name);