]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
copy: keep replaced target after publish errors
authordongshengyuan <545258830@qq.com>
Fri, 3 Jul 2026 06:44:40 +0000 (14:44 +0800)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 7 Jul 2026 16:41:26 +0000 (18:41 +0200)
Once link_tmpfile_at() succeeds, the target path
has been published. Avoid unlinking it on later
close or parent fsync failures when COPY_REPLACE
was used, as that can remove the replaced target.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
src/shared/copy.c

index f61b16caee0b4d7f651df4b32b06f0ef6925f3a8..21add1d5c0decb779911e4ca8137557af369f9ca 100644 (file)
@@ -1645,7 +1645,11 @@ int copy_file_atomic_at_full(
         return 0;
 
 fail:
-        (void) unlinkat(dir_fdt, to, 0);
+        /* link_tmpfile_at() succeeded, so 'to' is now published. In replacement mode, do not
+         * remove it again, as that may delete a pre-existing target replaced by this copy. */
+        if (!FLAGS_SET(copy_flags, COPY_REPLACE))
+                (void) unlinkat(dir_fdt, to, 0);
+
         return r;
 }