chiark / gitweb /
copy: use btrfs reflinking only whe we know we copy full files
authorLennart Poettering <lennart@poettering.net>
Fri, 12 Dec 2014 15:24:33 +0000 (16:24 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 12 Dec 2014 16:30:25 +0000 (17:30 +0100)
src/core/ima-setup.c
src/journal/coredump.c
src/machine/machine-dbus.c
src/shared/copy.c
src/shared/copy.h
src/systemctl/systemctl.c
src/sysusers/sysusers.c
src/test/test-copy.c

index 8e4fed1..0e0d16a 100644 (file)
@@ -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
index 8678ec6..a37e5eb 100644 (file)
@@ -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;
index 72ae6c6..f6fd9cf 100644 (file)
@@ -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);
 
index 233dbbc..b4a85c7 100644 (file)
@@ -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);
index 15faf54..201fe69 100644 (file)
@@ -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);
index 5ed430c..a75e9de 100644 (file)
@@ -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;
index 647eb57..0baa2c3 100644 (file)
@@ -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;
 
index d2cad08..d70a0be 100644 (file)
@@ -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);