mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
copy: Merge copy_directory() and copy_directory_fd() into copy_directory_at()
Let's merge these two into a single function that can handle both variants and more.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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|
|
||||
|
||||
@@ -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|
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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") {
|
||||
|
||||
Reference in New Issue
Block a user