chattr: optionally, return the old flags when updating them
This commit is contained in:
@@ -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)
|
||||
|
||||
+11
-5
@@ -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);
|
||||
|
||||
+2
-2
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user