cat: 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.

Reviewed by:	imp, rmacklem
Differential revision:	https://reviews.freebsd.org/D40882
This commit is contained in:
Martin Matuska 2023-07-08 20:31:38 +02:00
parent 70c00442d2
commit 8113cc8276

View file

@ -83,6 +83,7 @@ static void usage(void) __dead2;
static void scanfiles(char *argv[], int cooked);
#ifndef BOOTSTRAP_CAT
static void cook_cat(FILE *);
static ssize_t in_kernel_copy(int);
#endif
static void raw_cat(int);
@ -280,7 +281,16 @@ scanfiles(char *argv[], int cooked __unused)
}
#endif
} else {
#ifndef BOOTSTRAP_CAT
if (in_kernel_copy(fd) == -1) {
if (errno == EINVAL)
raw_cat(fd);
else
err(1, "stdout");
}
#else
raw_cat(fd);
#endif
if (fd != STDIN_FILENO)
close(fd);
}
@ -380,6 +390,21 @@ cook_cat(FILE *fp)
if (ferror(stdout))
err(1, "stdout");
}
static ssize_t
in_kernel_copy(int rfd)
{
int wfd;
ssize_t ret;
wfd = fileno(stdout);
ret = 1;
while (ret > 0)
ret = copy_file_range(rfd, NULL, wfd, NULL, SSIZE_MAX, 0);
return (ret);
}
#endif /* BOOTSTRAP_CAT */
static void