mirror of
https://github.com/systemd/systemd.git
synced 2026-08-04 23:20:32 +00:00
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.
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user