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:
Daan De Meyer
2023-06-01 13:42:39 +02:00
parent 6aea5ce814
commit f9f70e062d
6 changed files with 25 additions and 67 deletions

View 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)

View 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|

View 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|

View 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;

View 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);

View 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") {