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:
parent
70c00442d2
commit
8113cc8276
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user