git: c98a764c681f - main - cp(1): fix performance issue for large non-sparse file copies

Rick Macklem rmacklem at FreeBSD.org
Sun Jan 3 01:02:19 UTC 2021


The branch main has been updated by rmacklem:

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

commit c98a764c681f8b70812a9f13a6e61c96aa1a69d2
Author:     Rick Macklem <rmacklem at FreeBSD.org>
AuthorDate: 2021-01-03 00:58:43 +0000
Commit:     Rick Macklem <rmacklem at FreeBSD.org>
CommitDate: 2021-01-03 00:58:43 +0000

    cp(1): fix performance issue for large non-sparse file copies
    
    PR252358 reported a serious performance problem when
    copying a large non-sparse file on a UFS file system.
    This problem seems to have been caused by a large
    number of SEEK_HOLE operations, with one done
    for each copy_file_range(2) call.
    
    This patch modifies cp(1) to use a large (SSIZE_MAX)
    len argument, reducing the number of system calls
    and resolving the performance issue.
    
    While here, convert the type of the "rcount" from "int"
    to "ssize_t" so that it is consistent with that returned
    by both read(2) and copy_file_range(2).
    
    PR:     252358
    Reviewed by:    asomers
    Differential Revision:  https://reviews.freebsd.org/D27937
---
 bin/cp/utils.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/bin/cp/utils.c b/bin/cp/utils.c
index 1a3b5502145a..7742b0d0a516 100644
--- a/bin/cp/utils.c
+++ b/bin/cp/utils.c
@@ -74,11 +74,10 @@ __FBSDID("$FreeBSD$");
  */
 #define BUFSIZE_SMALL (MAXPHYS)
 
-static int
+static ssize_t
 copy_fallback(int from_fd, int to_fd, char *buf, size_t bufsize)
 {
-	int rcount;
-	ssize_t wresid, wcount = 0;
+	ssize_t rcount, wresid, wcount = 0;
 	char *bufp;
 
 	rcount = read(from_fd, buf, bufsize);
@@ -100,10 +99,10 @@ copy_file(const FTSENT *entp, int dne)
 	static char *buf = NULL;
 	static size_t bufsize;
 	struct stat *fs;
-	ssize_t wcount;
+	ssize_t rcount, wcount;
 	size_t wresid;
 	off_t wtotal;
-	int ch, checkch, from_fd, rcount, rval, to_fd;
+	int ch, checkch, from_fd, rval, to_fd;
 	char *bufp;
 #ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED
 	char *p;
@@ -236,7 +235,7 @@ copy_file(const FTSENT *entp, int dne)
 			do {
 				if (use_copy_file_range) {
 					rcount = copy_file_range(from_fd, NULL,
-			    		    to_fd, NULL, bufsize, 0);
+			    		    to_fd, NULL, SSIZE_MAX, 0);
 					if (rcount < 0 && errno == EINVAL) {
 						/* Prob a non-seekable FD */
 						use_copy_file_range = 0;


More information about the dev-commits-src-all mailing list