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. */
|
* it: the IMMUTABLE bit. Let's use this here, if this is requested. */
|
||||||
|
|
||||||
if (flags & BTRFS_SNAPSHOT_FALLBACK_IMMUTABLE)
|
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 {
|
} else {
|
||||||
r = btrfs_subvol_set_read_only(new_path, true);
|
r = btrfs_subvol_set_read_only(new_path, true);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "macro.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;
|
unsigned old_attr, new_attr;
|
||||||
struct stat st;
|
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))
|
if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
|
|
||||||
if (mask == 0)
|
if (mask == 0 && !previous)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
|
if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
new_attr = (old_attr & ~mask) | (value & mask);
|
new_attr = (old_attr & ~mask) | (value & mask);
|
||||||
if (new_attr == old_attr)
|
if (new_attr == old_attr) {
|
||||||
|
if (previous)
|
||||||
|
*previous = old_attr;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
|
if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
|
if (previous)
|
||||||
|
*previous = old_attr;
|
||||||
|
|
||||||
return 1;
|
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;
|
_cleanup_close_ int fd = -1;
|
||||||
|
|
||||||
assert(p);
|
assert(p);
|
||||||
|
@ -56,7 +62,7 @@ int chattr_path(const char *p, unsigned value, unsigned mask) {
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
return chattr_fd(fd, value, mask);
|
return chattr_fd(fd, value, mask, previous);
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_attr_fd(int fd, unsigned *ret) {
|
int read_attr_fd(int fd, unsigned *ret) {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
int chattr_fd(int fd, 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);
|
int chattr_path(const char *p, unsigned value, unsigned mask, unsigned *previous);
|
||||||
|
|
||||||
int read_attr_fd(int fd, unsigned *ret);
|
int read_attr_fd(int fd, unsigned *ret);
|
||||||
int read_attr_path(const char *p, 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)
|
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);
|
r = copy_file_fd(from, fdt, copy_flags);
|
||||||
if (r < 0) {
|
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)
|
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);
|
r = copy_file_fd(from, fdt, copy_flags);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|
|
@ -175,7 +175,7 @@ static int raw_import_maybe_convert_qcow2(RawImport *i) {
|
||||||
if (converted_fd < 0)
|
if (converted_fd < 0)
|
||||||
return log_error_errno(errno, "Failed to create %s: %m", t);
|
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)
|
if (r < 0)
|
||||||
log_warning_errno(r, "Failed to set file attributes on %s: %m", t);
|
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)
|
if (i->output_fd < 0)
|
||||||
return log_error_errno(errno, "Failed to open destination %s: %m", i->temp_path);
|
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)
|
if (r < 0)
|
||||||
log_warning_errno(r, "Failed to set file attributes on %s: %m", i->temp_path);
|
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)
|
if (converted_fd < 0)
|
||||||
return log_error_errno(errno, "Failed to create %s: %m", t);
|
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)
|
if (r < 0)
|
||||||
log_warning_errno(r, "Failed to set file attributes on %s: %m", t);
|
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
|
* performance on COW file systems like btrfs, since it
|
||||||
* reduces fragmentation caused by not allowing in-place
|
* reduces fragmentation caused by not allowing in-place
|
||||||
* writes. */
|
* 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)
|
if (r < 0)
|
||||||
log_warning_errno(r, "Failed to set file attributes on %s: %m", tp);
|
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)
|
if (r < 0)
|
||||||
return r;
|
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)
|
if (r < 0)
|
||||||
log_warning_errno(r, "Failed to set file attributes on %s, ignoring: %m", i->temp_path);
|
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
|
* reenable all the good bits COW usually provides
|
||||||
* (such as data checksumming). */
|
* (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);
|
(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
|
/* btrfs doesn't cope well with our write pattern and
|
||||||
* fragments heavily. Let's defrag all files we rotate */
|
* 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);
|
(void) btrfs_defrag(p);
|
||||||
|
|
||||||
log_warning_errno(r, "File %s corrupted or uncleanly shut down, renaming and replacing.", fname);
|
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
|
/* Enable secure remove, exclusion from dump, synchronous
|
||||||
* writing and in-place updating */
|
* 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)
|
if (r < 0)
|
||||||
log_warning_errno(r, "Failed to set file attributes: %m");
|
log_warning_errno(r, "Failed to set file attributes: %m");
|
||||||
|
|
||||||
|
|
|
@ -637,7 +637,7 @@ int image_remove(Image *i) {
|
||||||
|
|
||||||
case IMAGE_DIRECTORY:
|
case IMAGE_DIRECTORY:
|
||||||
/* Allow deletion of read-only directories */
|
/* 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);
|
r = rm_rf(i->path, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -736,7 +736,7 @@ int image_rename(Image *i, const char *new_name) {
|
||||||
(void) read_attr_path(i->path, &file_attr);
|
(void) read_attr_path(i->path, &file_attr);
|
||||||
|
|
||||||
if (file_attr & FS_IMMUTABLE_FL)
|
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_;
|
_fallthrough_;
|
||||||
case IMAGE_SUBVOLUME:
|
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 */
|
/* Restore the immutable bit, if it was set before */
|
||||||
if (file_attr & FS_IMMUTABLE_FL)
|
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->path, new_path);
|
||||||
free_and_replace(i->name, nn);
|
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
|
a read-only subvolume, but at least something, and
|
||||||
we can read the value back. */
|
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)
|
if (r < 0)
|
||||||
return r;
|
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)
|
if (procfs_fd < 0)
|
||||||
return log_error_errno(procfs_fd, "Failed to re-open '%s': %m", path);
|
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)
|
if (r < 0)
|
||||||
log_full_errno(IN_SET(r, -ENOTTY, -EOPNOTSUPP) ? LOG_DEBUG : LOG_WARNING,
|
log_full_errno(IN_SET(r, -ENOTTY, -EOPNOTSUPP) ? LOG_DEBUG : LOG_WARNING,
|
||||||
r,
|
r,
|
||||||
|
|
Loading…
Reference in a new issue