]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
copy: Merge copy_directory() and copy_directory_fd() into copy_directory_at()
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 1 Jun 2023 11:42:39 +0000 (13:42 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 6 Jun 2023 12:42:03 +0000 (14:42 +0200)
Let's merge these two into a single function that can handle both
variants and more.

src/dissect/dissect.c
src/import/import-fs.c
src/shared/btrfs-util.c
src/shared/copy.c
src/shared/copy.h
src/test/test-execute.c

index 5c742497d5cae6a7eea21b98e280b34ab01c7b67..25bdd68cd20295bef8edaff648bdfe35ca6d4346 100644 (file)
@@ -1286,7 +1286,7 @@ static int action_list_or_mtree_or_copy(DissectedImage *m, LoopDevice *d) {
                 }
 
                 /* Try to copy as directory? */
-                r = copy_directory_fd(source_fd, arg_target, COPY_REFLINK|COPY_MERGE_EMPTY|COPY_SIGINT|COPY_HARDLINKS);
+                r = copy_directory_at(source_fd, NULL, AT_FDCWD, arg_target, COPY_REFLINK|COPY_MERGE_EMPTY|COPY_SIGINT|COPY_HARDLINKS);
                 if (r >= 0)
                         return 0;
                 if (r != -ENOTDIR)
index d81dd13ffde4df06b37097c735e842d16b349bb9..221febea19c3647eaf7f20a4e8a0ee10d5953ff1 100644 (file)
@@ -206,9 +206,9 @@ static int import_fs(int argc, char *argv[], void *userdata) {
                                         progress_bytes,
                                         &progress);
                 else
-                        r = copy_directory_fd_full(
-                                        fd,
-                                        dest,
+                        r = copy_directory_at_full(
+                                        fd, NULL,
+                                        AT_FDCWD, dest,
                                         COPY_REFLINK|
                                         COPY_SAME_MOUNT|
                                         COPY_HARDLINKS|
index 16295a582377cc7db3aeb21a7f5abbe6464f6eea..03f9c0d0e69944544b0993721dfdeed53fd7eca3 100644 (file)
@@ -1561,8 +1561,9 @@ int btrfs_subvol_snapshot_fd_full(
                 } else if (r < 0)
                         return r;
 
-                r = copy_directory_fd_full(
-                                old_fd, new_path,
+                r = copy_directory_at_full(
+                                old_fd, NULL,
+                                AT_FDCWD, new_path,
                                 COPY_MERGE_EMPTY|
                                 COPY_REFLINK|
                                 COPY_SAME_MOUNT|
index 14b9b61d8a24e961e00635a42733ea6869061444..3216607ef8f30ffd957b5e937b66c45a0e0418bd 100644 (file)
@@ -1208,61 +1208,22 @@ int copy_tree_at_full(
         return 0;
 }
 
-static int sync_dir_by_flags(const char *path, CopyFlags copy_flags) {
+static int sync_dir_by_flags(int dir_fd, const char *path, CopyFlags copy_flags) {
+        assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
+        assert(path);
 
         if (copy_flags & COPY_SYNCFS)
-                return syncfs_path(AT_FDCWD, path);
+                return syncfs_path(dir_fd, path);
         if (copy_flags & COPY_FSYNC_FULL)
-                return fsync_parent_at(AT_FDCWD, path);
+                return fsync_parent_at(dir_fd, path);
 
         return 0;
 }
 
-int copy_directory_fd_full(
-                int dirfd,
-                const char *to,
-                CopyFlags copy_flags,
-                copy_progress_path_t progress_path,
-                copy_progress_bytes_t progress_bytes,
-                void *userdata) {
-
-        struct stat st;
-        int r;
-
-        assert(dirfd >= 0);
-        assert(to);
-
-        if (fstat(dirfd, &st) < 0)
-                return -errno;
-
-        r = stat_verify_directory(&st);
-        if (r < 0)
-                return r;
-
-        r = fd_copy_directory(
-                        dirfd, NULL,
-                        &st,
-                        AT_FDCWD, to,
-                        st.st_dev,
-                        COPY_DEPTH_MAX,
-                        UID_INVALID, GID_INVALID,
-                        copy_flags,
-                        NULL, NULL, NULL,
-                        progress_path,
-                        progress_bytes,
-                        userdata);
-        if (r < 0)
-                return r;
-
-        r = sync_dir_by_flags(to, copy_flags);
-        if (r < 0)
-                return r;
-
-        return 0;
-}
-
-int copy_directory_full(
+int copy_directory_at_full(
+                int dir_fdf,
                 const char *from,
+                int dir_fdt,
                 const char *to,
                 CopyFlags copy_flags,
                 copy_progress_path_t progress_path,
@@ -1272,10 +1233,11 @@ int copy_directory_full(
         struct stat st;
         int r;
 
-        assert(from);
+        assert(dir_fdf >= 0 || dir_fdf == AT_FDCWD);
+        assert(dir_fdt >= 0 || dir_fdt == AT_FDCWD);
         assert(to);
 
-        if (lstat(from, &st) < 0)
+        if (fstatat(dir_fdf, strempty(from), &st, AT_SYMLINK_NOFOLLOW|(isempty(from) ? AT_EMPTY_PATH : 0)) < 0)
                 return -errno;
 
         r = stat_verify_directory(&st);
@@ -1283,9 +1245,9 @@ int copy_directory_full(
                 return r;
 
         r = fd_copy_directory(
-                        AT_FDCWD, from,
+                        dir_fdf, from,
                         &st,
-                        AT_FDCWD, to,
+                        dir_fdt, to,
                         st.st_dev,
                         COPY_DEPTH_MAX,
                         UID_INVALID, GID_INVALID,
@@ -1297,7 +1259,7 @@ int copy_directory_full(
         if (r < 0)
                 return r;
 
-        r = sync_dir_by_flags(to, copy_flags);
+        r = sync_dir_by_flags(dir_fdt, to, copy_flags);
         if (r < 0)
                 return r;
 
index c4482eba7e1faf3f21e2cc32c6e4de07a383de96..9a0df9f4f5328265f104433698b96f2778024205 100644 (file)
@@ -82,14 +82,9 @@ static inline int copy_tree(const char *from, const char *to, uid_t override_uid
         return copy_tree_at_full(AT_FDCWD, from, AT_FDCWD, to, override_uid, override_gid, copy_flags, denylist, NULL, NULL, NULL);
 }
 
-int copy_directory_fd_full(int dirfd, const char *to, CopyFlags copy_flags, copy_progress_path_t progress_path, copy_progress_bytes_t progress_bytes, void *userdata);
-static inline int copy_directory_fd(int dirfd, const char *to, CopyFlags copy_flags) {
-        return copy_directory_fd_full(dirfd, to, copy_flags, NULL, NULL, NULL);
-}
-
-int copy_directory_full(const char *from, const char *to, CopyFlags copy_flags, copy_progress_path_t progress_path, copy_progress_bytes_t progress_bytes, void *userdata);
-static inline int copy_directory(const char *from, const char *to, CopyFlags copy_flags) {
-        return copy_directory_full(from, to, copy_flags, NULL, NULL, NULL);
+int copy_directory_at_full(int dir_fdf, const char *from, int dir_fdt, const char *to, CopyFlags copy_flags, copy_progress_path_t progress_path, copy_progress_bytes_t progress_bytes, void *userdata);
+static inline int copy_directory_at(int dir_fdf, const char *from, int dir_fdt, const char *to, CopyFlags copy_flags) {
+        return copy_directory_at_full(dir_fdf, from, dir_fdt, to, copy_flags, NULL, NULL, NULL);
 }
 
 int copy_bytes_full(int fdf, int fdt, uint64_t max_bytes, CopyFlags copy_flags, void **ret_remains, size_t *ret_remains_size, copy_progress_bytes_t progress, void *userdata);
index a07c837e3f5c0b57e4f5f6e5cde70f4cd385f8d8..a63afa873b9170f434690a3c888d1662447310d2 100644 (file)
@@ -1299,7 +1299,7 @@ static int prepare_ns(const char *process_name) {
 
                 /* Copy unit files to make them accessible even when unprivileged. */
                 assert_se(get_testdata_dir("test-execute/", &unit_dir) >= 0);
-                assert_se(copy_directory(unit_dir, PRIVATE_UNIT_DIR, COPY_MERGE_EMPTY) >= 0);
+                assert_se(copy_directory_at(AT_FDCWD, unit_dir, AT_FDCWD, PRIVATE_UNIT_DIR, COPY_MERGE_EMPTY) >= 0);
 
                 /* Prepare credstore like tmpfiles.d/credstore.conf for LoadCredential= tests. */
                 FOREACH_STRING(p, "/run/credstore", "/run/credstore.encrypted") {