]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
copy: make copy_bytes() support O_PATH fds
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 8 Apr 2023 08:33:25 +0000 (17:33 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 10 Apr 2023 20:17:10 +0000 (05:17 +0900)
src/shared/copy.c
src/test/test-copy.c

index 23d72ad1ca8527eea1fb9c175fccf180386c91ff..f283394545b85dc5632a03f007dfbcc071b26ecc 100644 (file)
@@ -157,6 +157,7 @@ int copy_bytes_full(
                 copy_progress_bytes_t progress,
                 void *userdata) {
 
+        _cleanup_close_ int fdf_opened = -EBADF, fdt_opened = -EBADF;
         bool try_cfr = true, try_sendfile = true, try_splice = true, copied_something = false;
         int r, nonblock_pipe = -1;
         size_t m = SSIZE_MAX; /* that is the maximum that sendfile and c_f_r accept */
@@ -177,6 +178,13 @@ int copy_bytes_full(
         if (ret_remains_size)
                 *ret_remains_size = 0;
 
+        fdf = fd_reopen_condition(fdf, O_CLOEXEC | O_NOCTTY | O_RDONLY, O_PATH, &fdf_opened);
+        if (fdf < 0)
+                return fdf;
+        fdt = fd_reopen_condition(fdt, O_CLOEXEC | O_NOCTTY | O_RDWR, O_PATH, &fdt_opened);
+        if (fdt < 0)
+                return fdt;
+
         /* Try btrfs reflinks first. This only works on regular, seekable files, hence let's check the file offsets of
          * source and destination first. */
         if ((copy_flags & COPY_REFLINK)) {
index 4cd83dbeeaab5f5927e101e40d899b6c641770bc..df08b7ed618734b32630d266a84d0bc80bb2893b 100644 (file)
@@ -301,7 +301,7 @@ static void test_copy_bytes_regular_file_one(const char *src, bool try_reflink,
 
         log_info("%s try_reflink=%s max_bytes=%" PRIu64, __func__, yes_no(try_reflink), max_bytes);
 
-        fd = open(src, O_RDONLY | O_CLOEXEC | O_NOCTTY);
+        fd = open(src, O_CLOEXEC | O_PATH);
         assert_se(fd >= 0);
 
         fd2 = mkostemp_safe(fn2);