copy: use btrfs reflinking only whe we know we copy full files
This commit is contained in:
parent
19ee32dc4d
commit
7430ec6ac0
|
@ -66,7 +66,7 @@ int ima_setup(void) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
r = copy_bytes(policyfd, imafd, -1);
|
||||
r = copy_bytes(policyfd, imafd, (off_t) -1, false);
|
||||
if (r < 0)
|
||||
log_error_errno(r, "Failed to load the IMA custom policy file "IMA_POLICY_PATH": %m");
|
||||
else
|
||||
|
|
|
@ -316,7 +316,7 @@ static int save_external_coredump(
|
|||
if (fd < 0)
|
||||
return log_error_errno(errno, "Failed to create coredump file %s: %m", tmp);
|
||||
|
||||
r = copy_bytes(STDIN_FILENO, fd, arg_process_size_max);
|
||||
r = copy_bytes(STDIN_FILENO, fd, arg_process_size_max, false);
|
||||
if (r == -EFBIG) {
|
||||
log_error("Coredump of %s (%s) is larger than configured processing limit, refusing.", info[INFO_PID], info[INFO_COMM]);
|
||||
goto fail;
|
||||
|
|
|
@ -344,7 +344,7 @@ int bus_machine_method_get_os_release(sd_bus *bus, sd_bus_message *message, void
|
|||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
r = copy_bytes(fd, pair[1], (off_t) -1);
|
||||
r = copy_bytes(fd, pair[1], (off_t) -1, false);
|
||||
if (r < 0)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "btrfs-util.h"
|
||||
#include "copy.h"
|
||||
|
||||
int copy_bytes(int fdf, int fdt, off_t max_bytes) {
|
||||
int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink) {
|
||||
bool try_sendfile = true;
|
||||
int r;
|
||||
|
||||
|
@ -33,10 +33,10 @@ int copy_bytes(int fdf, int fdt, off_t max_bytes) {
|
|||
assert(fdt >= 0);
|
||||
|
||||
/* Try btrfs reflinks first. */
|
||||
if (max_bytes == (off_t) -1) {
|
||||
if (try_reflink && max_bytes == (off_t) -1) {
|
||||
r = btrfs_reflink(fdf, fdt);
|
||||
if (r >= 0)
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
|
@ -131,7 +131,7 @@ static int fd_copy_regular(int df, const char *from, const struct stat *st, int
|
|||
if (fdt < 0)
|
||||
return -errno;
|
||||
|
||||
r = copy_bytes(fdf, fdt, (off_t) -1);
|
||||
r = copy_bytes(fdf, fdt, (off_t) -1, true);
|
||||
if (r < 0) {
|
||||
unlinkat(dt, to, 0);
|
||||
return r;
|
||||
|
@ -318,7 +318,7 @@ int copy_tree_fd(int dirfd, const char *to, bool merge) {
|
|||
return fd_copy_directory(dirfd, NULL, &st, AT_FDCWD, to, st.st_dev, merge);
|
||||
}
|
||||
|
||||
int copy_file_fd(const char *from, int fdt) {
|
||||
int copy_file_fd(const char *from, int fdt, bool try_reflink) {
|
||||
_cleanup_close_ int fdf = -1;
|
||||
|
||||
assert(from);
|
||||
|
@ -328,7 +328,7 @@ int copy_file_fd(const char *from, int fdt) {
|
|||
if (fdf < 0)
|
||||
return -errno;
|
||||
|
||||
return copy_bytes(fdf, fdt, (off_t) -1);
|
||||
return copy_bytes(fdf, fdt, (off_t) -1, try_reflink);
|
||||
}
|
||||
|
||||
int copy_file(const char *from, const char *to, int flags, mode_t mode) {
|
||||
|
@ -341,7 +341,7 @@ int copy_file(const char *from, const char *to, int flags, mode_t mode) {
|
|||
if (fdt < 0)
|
||||
return -errno;
|
||||
|
||||
r = copy_file_fd(from, fdt);
|
||||
r = copy_file_fd(from, fdt, true);
|
||||
if (r < 0) {
|
||||
close(fdt);
|
||||
unlink(to);
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
int copy_file_fd(const char *from, int to);
|
||||
int copy_file_fd(const char *from, int to, bool try_reflink);
|
||||
int copy_file(const char *from, const char *to, int flags, mode_t mode);
|
||||
int copy_tree(const char *from, const char *to, bool merge);
|
||||
int copy_tree_fd(int dirfd, const char *to, bool merge);
|
||||
int copy_bytes(int fdf, int fdt, off_t max_bytes);
|
||||
int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink);
|
||||
|
|
|
@ -4641,7 +4641,7 @@ static int cat(sd_bus *bus, char **args) {
|
|||
ansi_highlight_off());
|
||||
fflush(stdout);
|
||||
|
||||
r = copy_file_fd(fragment_path, STDOUT_FILENO);
|
||||
r = copy_file_fd(fragment_path, STDOUT_FILENO, false);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
|
||||
continue;
|
||||
|
@ -4656,7 +4656,7 @@ static int cat(sd_bus *bus, char **args) {
|
|||
ansi_highlight_off());
|
||||
fflush(stdout);
|
||||
|
||||
r = copy_file_fd(*path, STDOUT_FILENO);
|
||||
r = copy_file_fd(*path, STDOUT_FILENO, false);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to cat %s: %m", *path);
|
||||
continue;
|
||||
|
|
|
@ -215,7 +215,7 @@ static int make_backup(const char *target, const char *x) {
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = copy_bytes(src, fileno(dst), (off_t) -1);
|
||||
r = copy_bytes(src, fileno(dst), (off_t) -1, true);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
|
|
|
@ -67,8 +67,8 @@ static void test_copy_file_fd(void) {
|
|||
assert_se(out_fd >= 0);
|
||||
|
||||
assert_se(write_string_file(in_fn, text) == 0);
|
||||
assert_se(copy_file_fd("/a/file/which/does/not/exist/i/guess", out_fd) < 0);
|
||||
assert_se(copy_file_fd(in_fn, out_fd) >= 0);
|
||||
assert_se(copy_file_fd("/a/file/which/does/not/exist/i/guess", out_fd, true) < 0);
|
||||
assert_se(copy_file_fd(in_fn, out_fd, true) >= 0);
|
||||
assert_se(lseek(out_fd, SEEK_SET, 0) == 0);
|
||||
|
||||
assert_se(read(out_fd, buf, sizeof(buf)) == sizeof(text) - 1);
|
||||
|
|
Loading…
Reference in a new issue