mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-11 05:17:44 +03:00
chattr: optionally, return the old flags when updating them
This commit is contained in:
parent
8cbb7d8783
commit
db9a42545a
@ -1715,7 +1715,7 @@ int btrfs_subvol_snapshot_fd(int old_fd, const char *new_path, BtrfsSnapshotFlag
|
||||
* it: the IMMUTABLE bit. Let's use this here, if this is requested. */
|
||||
|
||||
if (flags & BTRFS_SNAPSHOT_FALLBACK_IMMUTABLE)
|
||||
(void) chattr_path(new_path, FS_IMMUTABLE_FL, FS_IMMUTABLE_FL);
|
||||
(void) chattr_path(new_path, FS_IMMUTABLE_FL, FS_IMMUTABLE_FL, NULL);
|
||||
} else {
|
||||
r = btrfs_subvol_set_read_only(new_path, true);
|
||||
if (r < 0)
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "macro.h"
|
||||
|
||||
int chattr_fd(int fd, unsigned value, unsigned mask) {
|
||||
int chattr_fd(int fd, unsigned value, unsigned mask, unsigned *previous) {
|
||||
unsigned old_attr, new_attr;
|
||||
struct stat st;
|
||||
|
||||
@ -28,23 +28,29 @@ int chattr_fd(int fd, unsigned value, unsigned mask) {
|
||||
if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
|
||||
return -ENOTTY;
|
||||
|
||||
if (mask == 0)
|
||||
if (mask == 0 && !previous)
|
||||
return 0;
|
||||
|
||||
if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
|
||||
return -errno;
|
||||
|
||||
new_attr = (old_attr & ~mask) | (value & mask);
|
||||
if (new_attr == old_attr)
|
||||
if (new_attr == old_attr) {
|
||||
if (previous)
|
||||
*previous = old_attr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
|
||||
return -errno;
|
||||
|
||||
if (previous)
|
||||
*previous = old_attr;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int chattr_path(const char *p, unsigned value, unsigned mask) {
|
||||
int chattr_path(const char *p, unsigned value, unsigned mask, unsigned *previous) {
|
||||
_cleanup_close_ int fd = -1;
|
||||
|
||||
assert(p);
|
||||
@ -56,7 +62,7 @@ int chattr_path(const char *p, unsigned value, unsigned mask) {
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
return chattr_fd(fd, value, mask);
|
||||
return chattr_fd(fd, value, mask, previous);
|
||||
}
|
||||
|
||||
int read_attr_fd(int fd, unsigned *ret) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
int chattr_fd(int fd, unsigned value, unsigned mask);
|
||||
int chattr_path(const char *p, unsigned value, unsigned mask);
|
||||
int chattr_fd(int fd, unsigned value, unsigned mask, unsigned *previous);
|
||||
int chattr_path(const char *p, unsigned value, unsigned mask, unsigned *previous);
|
||||
|
||||
int read_attr_fd(int fd, unsigned *ret);
|
||||
int read_attr_path(const char *p, unsigned *ret);
|
||||
|
@ -695,7 +695,7 @@ int copy_file(const char *from, const char *to, int flags, mode_t mode, unsigned
|
||||
}
|
||||
|
||||
if (chattr_flags != 0)
|
||||
(void) chattr_fd(fdt, chattr_flags, (unsigned) -1);
|
||||
(void) chattr_fd(fdt, chattr_flags, (unsigned) -1, NULL);
|
||||
|
||||
r = copy_file_fd(from, fdt, copy_flags);
|
||||
if (r < 0) {
|
||||
@ -743,7 +743,7 @@ int copy_file_atomic(const char *from, const char *to, mode_t mode, unsigned cha
|
||||
}
|
||||
|
||||
if (chattr_flags != 0)
|
||||
(void) chattr_fd(fdt, chattr_flags, (unsigned) -1);
|
||||
(void) chattr_fd(fdt, chattr_flags, (unsigned) -1, NULL);
|
||||
|
||||
r = copy_file_fd(from, fdt, copy_flags);
|
||||
if (r < 0)
|
||||
|
@ -175,7 +175,7 @@ static int raw_import_maybe_convert_qcow2(RawImport *i) {
|
||||
if (converted_fd < 0)
|
||||
return log_error_errno(errno, "Failed to create %s: %m", t);
|
||||
|
||||
r = chattr_fd(converted_fd, FS_NOCOW_FL, FS_NOCOW_FL);
|
||||
r = chattr_fd(converted_fd, FS_NOCOW_FL, FS_NOCOW_FL, NULL);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to set file attributes on %s: %m", t);
|
||||
|
||||
@ -260,7 +260,7 @@ static int raw_import_open_disk(RawImport *i) {
|
||||
if (i->output_fd < 0)
|
||||
return log_error_errno(errno, "Failed to open destination %s: %m", i->temp_path);
|
||||
|
||||
r = chattr_fd(i->output_fd, FS_NOCOW_FL, FS_NOCOW_FL);
|
||||
r = chattr_fd(i->output_fd, FS_NOCOW_FL, FS_NOCOW_FL, NULL);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to set file attributes on %s: %m", i->temp_path);
|
||||
|
||||
|
@ -237,7 +237,7 @@ static int raw_pull_maybe_convert_qcow2(RawPull *i) {
|
||||
if (converted_fd < 0)
|
||||
return log_error_errno(errno, "Failed to create %s: %m", t);
|
||||
|
||||
r = chattr_fd(converted_fd, FS_NOCOW_FL, FS_NOCOW_FL);
|
||||
r = chattr_fd(converted_fd, FS_NOCOW_FL, FS_NOCOW_FL, NULL);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to set file attributes on %s: %m", t);
|
||||
|
||||
@ -353,7 +353,7 @@ static int raw_pull_make_local_copy(RawPull *i) {
|
||||
* performance on COW file systems like btrfs, since it
|
||||
* reduces fragmentation caused by not allowing in-place
|
||||
* writes. */
|
||||
r = chattr_fd(dfd, FS_NOCOW_FL, FS_NOCOW_FL);
|
||||
r = chattr_fd(dfd, FS_NOCOW_FL, FS_NOCOW_FL, NULL);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to set file attributes on %s: %m", tp);
|
||||
|
||||
@ -595,7 +595,7 @@ static int raw_pull_job_on_open_disk_raw(PullJob *j) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = chattr_fd(j->disk_fd, FS_NOCOW_FL, FS_NOCOW_FL);
|
||||
r = chattr_fd(j->disk_fd, FS_NOCOW_FL, FS_NOCOW_FL, NULL);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to set file attributes on %s, ignoring: %m", i->temp_path);
|
||||
|
||||
|
@ -372,7 +372,7 @@ JournalFile* journal_file_close(JournalFile *f) {
|
||||
* reenable all the good bits COW usually provides
|
||||
* (such as data checksumming). */
|
||||
|
||||
(void) chattr_fd(f->fd, 0, FS_NOCOW_FL);
|
||||
(void) chattr_fd(f->fd, 0, FS_NOCOW_FL, NULL);
|
||||
(void) btrfs_defrag_fd(f->fd);
|
||||
}
|
||||
|
||||
@ -3563,7 +3563,7 @@ int journal_file_open_reliably(
|
||||
/* btrfs doesn't cope well with our write pattern and
|
||||
* fragments heavily. Let's defrag all files we rotate */
|
||||
|
||||
(void) chattr_path(p, 0, FS_NOCOW_FL);
|
||||
(void) chattr_path(p, 0, FS_NOCOW_FL, NULL);
|
||||
(void) btrfs_defrag(p);
|
||||
|
||||
log_warning_errno(r, "File %s corrupted or uncleanly shut down, renaming and replacing.", fname);
|
||||
|
@ -1732,7 +1732,7 @@ static int setup_keys(void) {
|
||||
|
||||
/* Enable secure remove, exclusion from dump, synchronous
|
||||
* writing and in-place updating */
|
||||
r = chattr_fd(fd, FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL, FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL);
|
||||
r = chattr_fd(fd, FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL, FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL, NULL);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to set file attributes: %m");
|
||||
|
||||
|
@ -637,7 +637,7 @@ int image_remove(Image *i) {
|
||||
|
||||
case IMAGE_DIRECTORY:
|
||||
/* Allow deletion of read-only directories */
|
||||
(void) chattr_path(i->path, 0, FS_IMMUTABLE_FL);
|
||||
(void) chattr_path(i->path, 0, FS_IMMUTABLE_FL, NULL);
|
||||
r = rm_rf(i->path, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -736,7 +736,7 @@ int image_rename(Image *i, const char *new_name) {
|
||||
(void) read_attr_path(i->path, &file_attr);
|
||||
|
||||
if (file_attr & FS_IMMUTABLE_FL)
|
||||
(void) chattr_path(i->path, 0, FS_IMMUTABLE_FL);
|
||||
(void) chattr_path(i->path, 0, FS_IMMUTABLE_FL, NULL);
|
||||
|
||||
_fallthrough_;
|
||||
case IMAGE_SUBVOLUME:
|
||||
@ -777,7 +777,7 @@ int image_rename(Image *i, const char *new_name) {
|
||||
|
||||
/* Restore the immutable bit, if it was set before */
|
||||
if (file_attr & FS_IMMUTABLE_FL)
|
||||
(void) chattr_path(new_path, FS_IMMUTABLE_FL, FS_IMMUTABLE_FL);
|
||||
(void) chattr_path(new_path, FS_IMMUTABLE_FL, FS_IMMUTABLE_FL, NULL);
|
||||
|
||||
free_and_replace(i->path, new_path);
|
||||
free_and_replace(i->name, nn);
|
||||
@ -927,7 +927,7 @@ int image_read_only(Image *i, bool b) {
|
||||
a read-only subvolume, but at least something, and
|
||||
we can read the value back. */
|
||||
|
||||
r = chattr_path(i->path, b ? FS_IMMUTABLE_FL : 0, FS_IMMUTABLE_FL);
|
||||
r = chattr_path(i->path, b ? FS_IMMUTABLE_FL : 0, FS_IMMUTABLE_FL, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -1232,7 +1232,7 @@ static int fd_set_attribute(Item *item, int fd, const char *path, const struct s
|
||||
if (procfs_fd < 0)
|
||||
return log_error_errno(procfs_fd, "Failed to re-open '%s': %m", path);
|
||||
|
||||
r = chattr_fd(procfs_fd, f, item->attribute_mask);
|
||||
r = chattr_fd(procfs_fd, f, item->attribute_mask, NULL);
|
||||
if (r < 0)
|
||||
log_full_errno(IN_SET(r, -ENOTTY, -EOPNOTSUPP) ? LOG_DEBUG : LOG_WARNING,
|
||||
r,
|
||||
|
Loading…
Reference in New Issue
Block a user