diff options
author | Lennart Poettering <lennart@poettering.net> | 2019-03-28 17:54:04 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2019-03-28 18:43:04 +0100 |
commit | 8a016c746ef4f7e9b5fcc5fc7086e80880d84608 (patch) | |
tree | 3de74a91ac4963ec214009b55c14fd72b1429712 /src/basic | |
parent | c3272fd4df4a2ff3ebc1b8d4024d56bc803a1b62 (diff) | |
download | systemd-8a016c746ef4f7e9b5fcc5fc7086e80880d84608.tar.gz |
util-lib: when copying files make sure to apply some chattrs early, some late
Some chattrs only work sensible if you set them right after opening a
file for create (think: FS_NOCOW_FL). Others only work when they are
applied when the file is fully written (think: FS_IMMUTABLE_FL). Let's
take that into account when copying files and applying a chattr to them.
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/chattr-util.h | 14 | ||||
-rw-r--r-- | src/basic/copy.c | 16 | ||||
-rw-r--r-- | src/basic/copy.h | 12 |
3 files changed, 32 insertions, 10 deletions
diff --git a/src/basic/chattr-util.h b/src/basic/chattr-util.h index 7570bba2fa..eb6bfbe461 100644 --- a/src/basic/chattr-util.h +++ b/src/basic/chattr-util.h @@ -1,6 +1,20 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +#include <linux/fs.h> + +#include "missing_fs.h" + +/* The chattr() flags to apply when creating a new file *before* writing to it. In particular, flags such as + * FS_NOCOW_FL don't work if applied a-posteriori. All other flags are fine (or even necessary, think + * FS_IMMUTABLE_FL!) to apply after writing to the files. */ +#define CHATTR_EARLY_FL \ + (FS_NOATIME_FL | \ + FS_COMPR_FL | \ + FS_NOCOW_FL | \ + FS_NOCOMP_FL | \ + FS_PROJINHERIT_FL) + int chattr_fd(int fd, unsigned value, unsigned mask, unsigned *previous); int chattr_path(const char *p, unsigned value, unsigned mask, unsigned *previous); diff --git a/src/basic/copy.c b/src/basic/copy.c index 2f36c8eb87..eed9cfdff7 100644 --- a/src/basic/copy.c +++ b/src/basic/copy.c @@ -755,6 +755,7 @@ int copy_file_full( int flags, mode_t mode, unsigned chattr_flags, + unsigned chattr_mask, CopyFlags copy_flags, copy_progress_bytes_t progress_bytes, void *userdata) { @@ -770,8 +771,8 @@ int copy_file_full( return -errno; } - if (chattr_flags != 0) - (void) chattr_fd(fdt, chattr_flags, (unsigned) -1, NULL); + if (chattr_mask != 0) + (void) chattr_fd(fdt, chattr_flags, chattr_mask & CHATTR_EARLY_FL, NULL); r = copy_file_fd_full(from, fdt, copy_flags, progress_bytes, userdata); if (r < 0) { @@ -780,6 +781,9 @@ int copy_file_full( return r; } + if (chattr_mask != 0) + (void) chattr_fd(fdt, chattr_flags, chattr_mask & ~CHATTR_EARLY_FL, NULL); + if (close(fdt) < 0) { unlink_noerrno(to); return -errno; @@ -793,6 +797,7 @@ int copy_file_atomic_full( const char *to, mode_t mode, unsigned chattr_flags, + unsigned chattr_mask, CopyFlags copy_flags, copy_progress_bytes_t progress_bytes, void *userdata) { @@ -826,8 +831,8 @@ int copy_file_atomic_full( return fdt; } - if (chattr_flags != 0) - (void) chattr_fd(fdt, chattr_flags, (unsigned) -1, NULL); + if (chattr_mask != 0) + (void) chattr_fd(fdt, chattr_flags, chattr_mask & CHATTR_EARLY_FL, NULL); r = copy_file_fd_full(from, fdt, copy_flags, progress_bytes, userdata); if (r < 0) @@ -845,6 +850,9 @@ int copy_file_atomic_full( return r; } + if (chattr_mask != 0) + (void) chattr_fd(fdt, chattr_flags, chattr_mask & ~CHATTR_EARLY_FL, NULL); + t = mfree(t); return 0; } diff --git a/src/basic/copy.h b/src/basic/copy.h index a33546d3ab..51ea4d51eb 100644 --- a/src/basic/copy.h +++ b/src/basic/copy.h @@ -25,14 +25,14 @@ static inline int copy_file_fd(const char *from, int to, CopyFlags copy_flags) { return copy_file_fd_full(from, to, copy_flags, NULL, NULL); } -int copy_file_full(const char *from, const char *to, int open_flags, mode_t mode, unsigned chattr_flags, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata); -static inline int copy_file(const char *from, const char *to, int open_flags, mode_t mode, unsigned chattr_flags, CopyFlags copy_flags) { - return copy_file_full(from, to, open_flags, mode, chattr_flags, copy_flags, NULL, NULL); +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); +static inline int copy_file(const char *from, const char *to, int open_flags, mode_t mode, unsigned chattr_flags, unsigned chattr_mask, CopyFlags copy_flags) { + return copy_file_full(from, to, open_flags, mode, chattr_flags, chattr_mask, copy_flags, NULL, NULL); } -int copy_file_atomic_full(const char *from, const char *to, mode_t mode, unsigned chattr_flags, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata); -static inline int copy_file_atomic(const char *from, const char *to, mode_t mode, unsigned chattr_flags, CopyFlags copy_flags) { - return copy_file_atomic_full(from, to, mode, chattr_flags, copy_flags, NULL, NULL); +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); +static inline int copy_file_atomic(const char *from, const char *to, mode_t mode, unsigned chattr_flags, unsigned chattr_mask, CopyFlags copy_flags) { + return copy_file_atomic_full(from, to, mode, chattr_flags, chattr_mask, copy_flags, NULL, NULL); } 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, copy_progress_path_t progress_path, copy_progress_bytes_t progress_bytes, void *userdata); |