]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
copy: Invoke hardlink context cleanup before restoring timestamps
authorAndreas Stührk <andreas.stuehrk@yaxi.tech>
Tue, 25 Feb 2025 23:05:41 +0000 (00:05 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 4 Mar 2025 14:45:13 +0000 (15:45 +0100)
When hardlink recreation is requested, it creates temporary files that
will be deleted once the context is destroyed. The deletion
(potentially) updates the directory's timestamps, so it's crucial that
the deletion happens before the directory timestamps are restored when
`COPY_RESTORE_DIRECTORY_TIMESTAMPS` is requested.

(cherry picked from commit b66291444b8d4022ce68121af8e6f99d29ebefd0)

src/shared/copy.c

index 5221397da5dbf0044f3eb8c68814ac29d8ceae8c..27b517e21aa3f476ba65ff665a2617370bf05e75 100644 (file)
@@ -1178,11 +1178,16 @@ finish:
                 if (fchmod(fdt, st->st_mode & 07777) < 0)
                         r = -errno;
 
+                /* Run hardlink context cleanup now because it potentially changes timestamps */
+                hardlink_context_destroy(&our_hardlink_context);
                 (void) copy_xattr(dirfd(d), NULL, fdt, NULL, copy_flags);
                 (void) futimens(fdt, (struct timespec[]) { st->st_atim, st->st_mtim });
-        } else if (FLAGS_SET(copy_flags, COPY_RESTORE_DIRECTORY_TIMESTAMPS))
+        } else if (FLAGS_SET(copy_flags, COPY_RESTORE_DIRECTORY_TIMESTAMPS)) {
+                /* Run hardlink context cleanup now because it potentially changes timestamps */
+                hardlink_context_destroy(&our_hardlink_context);
                 /* If the directory already exists, make sure the timestamps stay the same as before. */
                 (void) futimens(fdt, (struct timespec[]) { dt_st.st_atim, dt_st.st_mtim });
+        }
 
         if (copy_flags & COPY_FSYNC_FULL) {
                 if (fsync(fdt) < 0)