aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorAlan Somers <asomers@FreeBSD.org>2020-09-10 02:48:55 +0000
committerAlan Somers <asomers@FreeBSD.org>2020-09-10 02:48:55 +0000
commitc01816a97fd516359000b1f0635f320b77ec0b00 (patch)
tree6a247f8e46add2a2f72da79d1fa74b069af65255 /bin
parent5c74d551d2c5618b41e741eaa3af84bfc7d79c88 (diff)
downloadsrc-c01816a97fd516359000b1f0635f320b77ec0b00.tar.gz
src-c01816a97fd516359000b1f0635f320b77ec0b00.zip
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
Notes
Notes: svn path=/head/; revision=365549
Diffstat (limited to 'bin')
-rw-r--r--bin/cp/utils.c31
1 files 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) {