From 7430ec6ac08f2c0416d9f806964c46b30f3862b2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 12 Dec 2014 16:24:33 +0100 Subject: [PATCH] copy: use btrfs reflinking only whe we know we copy full files --- src/core/ima-setup.c | 2 +- src/journal/coredump.c | 2 +- src/machine/machine-dbus.c | 2 +- src/shared/copy.c | 14 +++++++------- src/shared/copy.h | 4 ++-- src/systemctl/systemctl.c | 4 ++-- src/sysusers/sysusers.c | 2 +- src/test/test-copy.c | 4 ++-- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/core/ima-setup.c b/src/core/ima-setup.c index 8e4fed17e..0e0d16a7c 100644 --- a/src/core/ima-setup.c +++ b/src/core/ima-setup.c @@ -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 diff --git a/src/journal/coredump.c b/src/journal/coredump.c index 8678ec6a5..a37e5eb8a 100644 --- a/src/journal/coredump.c +++ b/src/journal/coredump.c @@ -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; diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index 72ae6c653..f6fd9cf36 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -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); diff --git a/src/shared/copy.c b/src/shared/copy.c index 233dbbccc..b4a85c7bf 100644 --- a/src/shared/copy.c +++ b/src/shared/copy.c @@ -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); diff --git a/src/shared/copy.h b/src/shared/copy.h index 15faf548a..201fe692c 100644 --- a/src/shared/copy.h +++ b/src/shared/copy.h @@ -24,8 +24,8 @@ #include #include -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); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 5ed430c82..a75e9dee1 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -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; diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 647eb577a..0baa2c39d 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -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; diff --git a/src/test/test-copy.c b/src/test/test-copy.c index d2cad08cb..d70a0be2a 100644 --- a/src/test/test-copy.c +++ b/src/test/test-copy.c @@ -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); -- 2.30.2