]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
chattr: optionally, return the old flags when updating them
authorLennart Poettering <lennart@poettering.net>
Mon, 25 Jun 2018 18:04:07 +0000 (20:04 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 8 Oct 2018 19:40:44 +0000 (21:40 +0200)
src/basic/btrfs-util.c
src/basic/chattr-util.c
src/basic/chattr-util.h
src/basic/copy.c
src/import/import-raw.c
src/import/pull-raw.c
src/journal/journal-file.c
src/journal/journalctl.c
src/shared/machine-image.c
src/tmpfiles/tmpfiles.c

index 0308048b7f8da9c49026d6d6e66d8f0a38d541af..1c9c5fd162b9ce890465a61fc5dd37add1889617 100644 (file)
@@ -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)
index 4ec14515eb38d5b44be64c8eac4766df8e78eb41..235cfb9bd752e19df84500bd1cffa7a9cf8d1076 100644 (file)
@@ -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) {
index 0c0816344a2eca521e383e659447640845a9fa73..7570bba2fa44d96ea01cf61a3ddbff06c5297b0e 100644 (file)
@@ -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);
index e06a503a2948c4a57a6b25eab2d0007ccb30896a..714cbb8fc3d1dda179839ef61c0624a1a6d86679 100644 (file)
@@ -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)
index 4537c4210cadd2e425309e0bb3ae235817203786..f62247cabdf12b74b04577480ed84da54766a069 100644 (file)
@@ -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);
 
index e68f197c7971eb2ea10b9bd26889cc70f4957e98..96800ac8a6d9f5522ccbf68cd34a193baaf5c302 100644 (file)
@@ -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);
 
index ee6e25e5e82fccf0b217dde1ca10ee9bed2cc54e..e9dddbc0d79ed8df94d769bfd757ac6104e93411 100644 (file)
@@ -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);
index 2f8d2e9596f201c2433dee918db11864939ffd3b..8bed6df891a973f85529bff0c96d1dbe7051c59a 100644 (file)
@@ -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");
 
index 52cf461109f9e6a823832f1306a7acd56a9d5b46..0344771a6093f245978cb2d891eade9df71b64d7 100644 (file)
@@ -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;
 
index e994be66df47e9d69e890f1e02a1ef110662adfd..1b3cb5fbd3780bcfb0354a5eccc60682bc1b3789 100644 (file)
@@ -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,