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-06 14:42:03 +02:00
parent 6aea5ce814
commit f9f70e062d
6 changed files with 25 additions and 67 deletions
+3 -2
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|
+14 -52
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;
+3 -8
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);