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);