Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 8 Jul 2023 19:52:01 GMT
From:      Martin Matuska <mm@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 5a50d52f112a - main - xinstall: use copy_file_range(2) with fallback to previous behavior
Message-ID:  <202307081952.368Jq1JY092060@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by mm:

URL: https://cgit.FreeBSD.org/src/commit/?id=5a50d52f112a86ebd0696da6564c7c7befa27f5d

commit 5a50d52f112a86ebd0696da6564c7c7befa27f5d
Author:     Martin Matuska <mm@FreeBSD.org>
AuthorDate: 2023-07-08 19:46:46 +0000
Commit:     Martin Matuska <mm@FreeBSD.org>
CommitDate: 2023-07-08 19:51:21 +0000

    xinstall: use copy_file_range(2) with fallback to previous behavior
    
    This allows to use special filesystem features like server-side
    copying on NFS 4.2 or block cloning on OpenZFS 2.2.
    
    Note: copy_file_range(2) is not used when a digest calculation is
    requested as this would require to read the input file twice.
    
    Reviewed by:    asomers, imp, rmacklem
    Differential revision:  https://reviews.freebsd.org/D40898
---
 usr.bin/xinstall/xinstall.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c
index b0e52453ca29..8dace862ef1e 100644
--- a/usr.bin/xinstall/xinstall.c
+++ b/usr.bin/xinstall/xinstall.c
@@ -1300,6 +1300,7 @@ copy(int from_fd, const char *from_name, int to_fd, const char *to_name,
 	static size_t bufsize;
 	int nr, nw;
 	int serrno;
+	ssize_t ret;
 	char *p;
 	int done_copy;
 	DIGEST_CTX ctx;
@@ -1310,6 +1311,26 @@ copy(int from_fd, const char *from_name, int to_fd, const char *to_name,
 	if (lseek(to_fd, (off_t)0, SEEK_SET) == (off_t)-1)
 		err(EX_OSERR, "lseek: %s", to_name);
 
+	/* Try copy_file_range() if no digest is requested */
+	if (digesttype == DIGEST_NONE) {
+		ret = 1;
+		while (ret > 0) {
+			ret = copy_file_range(from_fd, NULL, to_fd, NULL,
+			    SSIZE_MAX, 0);
+		}
+		if (ret == 0) {
+			/* DIGEST_NONE always returns NULL */
+			return (NULL);
+		}
+		if (errno != EINVAL) {
+			serrno = errno;
+			(void)unlink(to_name);
+			errno = serrno;
+			err(EX_OSERR, "%s", to_name);
+		}
+		/* Fall back */
+	}
+
 	digest_init(&ctx);
 
 	done_copy = 0;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202307081952.368Jq1JY092060>