1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
10 #include <sys/types.h>
14 typedef enum CopyFlags
{
15 COPY_REFLINK
= 1 << 0, /* Try to reflink */
16 COPY_MERGE
= 1 << 1, /* Merge existing trees with our new one to copy */
17 COPY_REPLACE
= 1 << 2, /* Replace an existing file if there's one */
18 COPY_SAME_MOUNT
= 1 << 3, /* Don't descend recursively into other file systems, across mount point boundaries */
19 COPY_MERGE_EMPTY
= 1 << 4, /* Merge an existing, empty directory with our new tree to copy */
20 COPY_CRTIME
= 1 << 5, /* Generate a user.crtime_usec xattr off the source crtime if there is one, on copying */
21 COPY_SIGINT
= 1 << 6, /* Check for SIGINT regularly and return EINTR if seen (caller needs to block SIGINT) */
22 COPY_SIGTERM
= 1 << 7, /* ditto, but for SIGTERM */
23 COPY_MAC_CREATE
= 1 << 8, /* Create files with the correct MAC label (currently SELinux only) */
24 COPY_HARDLINKS
= 1 << 9, /* Try to reproduce hard links */
25 COPY_FSYNC
= 1 << 10, /* fsync() after we are done */
26 COPY_FSYNC_FULL
= 1 << 11, /* fsync_full() after we are done */
27 COPY_SYNCFS
= 1 << 12, /* syncfs() the *top-level* dir after we are done */
28 COPY_ALL_XATTRS
= 1 << 13, /* Preserve all xattrs when copying, not just those in the user namespace */
29 COPY_HOLES
= 1 << 14, /* Copy holes */
30 COPY_GRACEFUL_WARN
= 1 << 15, /* Skip copying file types that aren't supported by the target filesystem */
33 typedef enum DenyType
{
34 DENY_DONT
= 0, /* we want INT_TO_PTR(DENY_DONT) to map to NULL */
38 _DENY_TYPE_INVALID
= -EINVAL
,
41 typedef int (*copy_progress_bytes_t
)(uint64_t n_bytes
, void *userdata
);
42 typedef int (*copy_progress_path_t
)(const char *path
, const struct stat
*st
, void *userdata
);
44 int copy_file_fd_at_full(int dir_fdf
, const char *from
, int to
, CopyFlags copy_flags
, copy_progress_bytes_t progress
, void *userdata
);
45 static inline int copy_file_fd_at(int dir_fdf
, const char *from
, int to
, CopyFlags copy_flags
, copy_progress_bytes_t progress
, void *userdata
) {
46 return copy_file_fd_at_full(dir_fdf
, from
, to
, copy_flags
, progress
, userdata
);
48 static inline int copy_file_fd_full(const char *from
, int to
, CopyFlags copy_flags
) {
49 return copy_file_fd_at_full(AT_FDCWD
, from
, to
, copy_flags
, NULL
, NULL
);
51 static inline int copy_file_fd(const char *from
, int to
, CopyFlags copy_flags
) {
52 return copy_file_fd_at(AT_FDCWD
, from
, to
, copy_flags
, NULL
, NULL
);
55 int copy_file_at_full(int dir_fdf
, const char *from
, int dir_fdt
, const char *to
, int open_flags
, mode_t mode
, unsigned chattr_flags
, unsigned chattr_mask
, CopyFlags copy_flags
, copy_progress_bytes_t progress
, void *userdata
);
56 static inline int copy_file_at(int dir_fdf
, const char *from
, int dir_fdt
, const char *to
, int open_flags
, mode_t mode
, CopyFlags copy_flags
) {
57 return copy_file_at_full(dir_fdf
, from
, dir_fdt
, to
, open_flags
, mode
, 0, 0, copy_flags
, NULL
, NULL
);
59 static inline int copy_file_full(const char *from
, const char *to
, int open_flags
, mode_t mode
, unsigned chattr_flags
, unsigned chattr_mask
, CopyFlags copy_flags
, copy_progress_bytes_t progress
, void *userdata
) {
60 return copy_file_at_full(AT_FDCWD
, from
, AT_FDCWD
, to
, open_flags
, mode
, chattr_flags
, chattr_mask
, copy_flags
, progress
, userdata
);
62 static inline int copy_file(const char *from
, const char *to
, int open_flags
, mode_t mode
, CopyFlags copy_flags
) {
63 return copy_file_at(AT_FDCWD
, from
, AT_FDCWD
, to
, open_flags
, mode
, copy_flags
);
66 int copy_file_atomic_at_full(int dir_fdf
, const char *from
, int dir_fdt
, const char *to
, mode_t mode
, unsigned chattr_flags
, unsigned chattr_mask
, CopyFlags copy_flags
, copy_progress_bytes_t progress
, void *userdata
);
67 static inline int copy_file_atomic_at(int dir_fdf
, const char *from
, int dir_fdt
, const char *to
, mode_t mode
, CopyFlags copy_flags
) {
68 return copy_file_atomic_at_full(dir_fdf
, from
, dir_fdt
, to
, mode
, 0, 0, copy_flags
, NULL
, NULL
);
70 static inline int copy_file_atomic_full(const char *from
, const char *to
, mode_t mode
, unsigned chattr_flags
, unsigned chattr_mask
, CopyFlags copy_flags
, copy_progress_bytes_t progress
, void *userdata
) {
71 return copy_file_atomic_at_full(AT_FDCWD
, from
, AT_FDCWD
, to
, mode
, 0, 0, copy_flags
, NULL
, NULL
);
73 static inline int copy_file_atomic(const char *from
, const char *to
, mode_t mode
, CopyFlags copy_flags
) {
74 return copy_file_atomic_full(from
, to
, mode
, 0, 0, copy_flags
, NULL
, NULL
);
77 int copy_tree_at_full(int fdf
, const char *from
, int fdt
, const char *to
, uid_t override_uid
, gid_t override_gid
, CopyFlags copy_flags
, Hashmap
*denylist
, copy_progress_path_t progress_path
, copy_progress_bytes_t progress_bytes
, void *userdata
);
78 static inline int copy_tree_at(int fdf
, const char *from
, int fdt
, const char *to
, uid_t override_uid
, gid_t override_gid
, CopyFlags copy_flags
, Hashmap
*denylist
) {
79 return copy_tree_at_full(fdf
, from
, fdt
, to
, override_uid
, override_gid
, copy_flags
, denylist
, NULL
, NULL
, NULL
);
81 static inline int copy_tree(const char *from
, const char *to
, uid_t override_uid
, gid_t override_gid
, CopyFlags copy_flags
, Hashmap
*denylist
) {
82 return copy_tree_at_full(AT_FDCWD
, from
, AT_FDCWD
, to
, override_uid
, override_gid
, copy_flags
, denylist
, NULL
, NULL
, NULL
);
85 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
);
86 static inline int copy_directory_at(int dir_fdf
, const char *from
, int dir_fdt
, const char *to
, CopyFlags copy_flags
) {
87 return copy_directory_at_full(dir_fdf
, from
, dir_fdt
, to
, copy_flags
, NULL
, NULL
, NULL
);
90 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
);
91 static inline int copy_bytes(int fdf
, int fdt
, uint64_t max_bytes
, CopyFlags copy_flags
) {
92 return copy_bytes_full(fdf
, fdt
, max_bytes
, copy_flags
, NULL
, NULL
, NULL
, NULL
);
95 int copy_times(int fdf
, int fdt
, CopyFlags flags
);
96 int copy_access(int fdf
, int fdt
);
97 int copy_rights_with_fallback(int fdf
, int fdt
, const char *patht
);
98 static inline int copy_rights(int fdf
, int fdt
) {
99 return copy_rights_with_fallback(fdf
, fdt
, NULL
); /* no fallback */
101 int copy_xattr(int df
, const char *from
, int dt
, const char *to
, CopyFlags copy_flags
);
103 int reflink(int infd
, int outfd
);
104 int reflink_range(int infd
, uint64_t in_offset
, int outfd
, uint64_t out_offset
, uint64_t sz
);