From c01816a97fd516359000b1f0635f320b77ec0b00 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Thu, 10 Sep 2020 02:48:55 +0000 Subject: [PATCH] cp: use copy_file_range(2) This has three advantages over write(2)/read(2): * Fewer context switches and data copies * Mostly preserves a file's sparseness * On some file systems (currently NFS 4.2) the file system will perform the copy in an especially efficient way. Reviewed by: rmacklem MFC after: 2 weeks Sponsored by: Axcient Differential Revision: https://reviews.freebsd.org/D26377 --- bin/cp/utils.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/bin/cp/utils.c b/bin/cp/utils.c index 3c76e85e493f..cca12202a70a 100644 --- a/bin/cp/utils.c +++ b/bin/cp/utils.c @@ -212,27 +212,16 @@ copy_file(const FTSENT *entp, int dne) err(1, "Not enough memory"); } wtotal = 0; - while ((rcount = read(from_fd, buf, bufsize)) > 0) { - for (bufp = buf, wresid = rcount; ; - bufp += wcount, wresid -= wcount) { - wcount = write(to_fd, bufp, wresid); - if (wcount <= 0) - break; - wtotal += wcount; - if (info) { - info = 0; - (void)fprintf(stderr, - "%s -> %s %3d%%\n", - entp->fts_path, to.p_path, - cp_pct(wtotal, fs->st_size)); - } - if (wcount >= (ssize_t)wresid) - break; - } - if (wcount != (ssize_t)wresid) { - warn("%s", to.p_path); - rval = 1; - break; + while ((rcount = copy_file_range(from_fd, NULL, + to_fd, NULL, bufsize, 0)) > 0) + { + wtotal += rcount; + if (info) { + info = 0; + (void)fprintf(stderr, + "%s -> %s %3d%%\n", + entp->fts_path, to.p_path, + cp_pct(wtotal, fs->st_size)); } } if (rcount < 0) {