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:
@@ -83,6 +83,7 @@ static void usage(void) __dead2;
|
|||||||
static void scanfiles(char *argv[], int cooked);
|
static void scanfiles(char *argv[], int cooked);
|
||||||
#ifndef BOOTSTRAP_CAT
|
#ifndef BOOTSTRAP_CAT
|
||||||
static void cook_cat(FILE *);
|
static void cook_cat(FILE *);
|
||||||
|
static ssize_t in_kernel_copy(int);
|
||||||
#endif
|
#endif
|
||||||
static void raw_cat(int);
|
static void raw_cat(int);
|
||||||
|
|
||||||
@@ -280,7 +281,16 @@ scanfiles(char *argv[], int cooked __unused)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#ifndef BOOTSTRAP_CAT
|
||||||
|
if (in_kernel_copy(fd) == -1) {
|
||||||
|
if (errno == EINVAL)
|
||||||
raw_cat(fd);
|
raw_cat(fd);
|
||||||
|
else
|
||||||
|
err(1, "stdout");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
raw_cat(fd);
|
||||||
|
#endif
|
||||||
if (fd != STDIN_FILENO)
|
if (fd != STDIN_FILENO)
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
@@ -380,6 +390,21 @@ cook_cat(FILE *fp)
|
|||||||
if (ferror(stdout))
|
if (ferror(stdout))
|
||||||
err(1, "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 */
|
#endif /* BOOTSTRAP_CAT */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
Reference in New Issue
Block a user