mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 08:25:20 +09:00
tree-wide: Handle EINVAL as not supported for chattr_xxx()
F2FS returns EINVAL from FS_IOC_SETFLAGS when trying to set FS_NOCOW_FL. Let's handle this by treating EINVAL as not supported. While we're at it, make sure we use ERRNO_IS_IOCTL_NOT_SUPPORTED() across the tree instead of ERRNO_IS_NOT_SUPPORTED() when calling any of the chattr_xxx() functions. Fixes #37593
This commit is contained in:
@@ -80,16 +80,15 @@ int chattr_full(
|
||||
errno = EINVAL;
|
||||
}
|
||||
|
||||
if ((errno != EINVAL && !ERRNO_IS_NOT_SUPPORTED(errno)) ||
|
||||
!FLAGS_SET(flags, CHATTR_FALLBACK_BITWISE))
|
||||
if (!ERRNO_IS_IOCTL_NOT_SUPPORTED(errno) || !FLAGS_SET(flags, CHATTR_FALLBACK_BITWISE))
|
||||
return -errno;
|
||||
|
||||
/* When -EINVAL is returned, we assume that incompatible attributes are simultaneously
|
||||
* specified. E.g., compress(c) and nocow(C) attributes cannot be set to files on btrfs.
|
||||
* As a fallback, let's try to set attributes one by one.
|
||||
/* When -EINVAL is returned, incompatible attributes might be simultaneously specified. E.g.,
|
||||
* compress(c) and nocow(C) attributes cannot be set to files on btrfs. As a fallback, let's try to
|
||||
* set attributes one by one.
|
||||
*
|
||||
* Also, when we get EOPNOTSUPP (or a similar error code) we assume a flag might just not be
|
||||
* supported, and we can ignore it too */
|
||||
* Alternatively, when we get EINVAL or EOPNOTSUPP (or a similar error code) we assume a flag might
|
||||
* just not be supported, and we can ignore it too */
|
||||
|
||||
unsigned current_attr = old_attr;
|
||||
|
||||
@@ -110,7 +109,7 @@ int chattr_full(
|
||||
|
||||
/* Ensures that we record whether only EOPNOTSUPP&friends are encountered, or if a more serious
|
||||
* error (thus worth logging at a different level, etc) was seen too. */
|
||||
if (set_flags_errno == 0 || !ERRNO_IS_NOT_SUPPORTED(errno))
|
||||
if (set_flags_errno == 0 || !ERRNO_IS_IOCTL_NOT_SUPPORTED(errno))
|
||||
set_flags_errno = -errno;
|
||||
|
||||
continue;
|
||||
@@ -125,10 +124,10 @@ int chattr_full(
|
||||
if (ret_final)
|
||||
*ret_final = current_attr;
|
||||
|
||||
/* -ENOANO indicates that some attributes cannot be set. ERRNO_IS_NOT_SUPPORTED indicates that all
|
||||
* encountered failures were due to flags not supported by the FS, so return a specific error in
|
||||
/* -ENOANO indicates that some attributes cannot be set. ERRNO_IS_IOCTL_NOT_SUPPORTED indicates that
|
||||
* all encountered failures were due to flags not supported by the FS, so return a specific error in
|
||||
* that case, so callers can handle it properly (e.g.: tmpfiles.d can use debug level logging). */
|
||||
return current_attr == new_attr ? 1 : ERRNO_IS_NOT_SUPPORTED(set_flags_errno) ? set_flags_errno : -ENOANO;
|
||||
return current_attr == new_attr ? 1 : ERRNO_IS_IOCTL_NOT_SUPPORTED(set_flags_errno) ? set_flags_errno : -ENOANO;
|
||||
}
|
||||
|
||||
int read_attr_fd(int fd, unsigned *ret) {
|
||||
|
||||
@@ -1280,7 +1280,7 @@ int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_
|
||||
|
||||
if (FLAGS_SET(xopen_flags, XO_NOCOW)) {
|
||||
r = chattr_fd(fd, FS_NOCOW_FL, FS_NOCOW_FL);
|
||||
if (r < 0 && !ERRNO_IS_NOT_SUPPORTED(r))
|
||||
if (r < 0 && !ERRNO_IS_IOCTL_NOT_SUPPORTED(r))
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
@@ -2304,7 +2304,7 @@ int home_create_luks(
|
||||
|
||||
r = chattr_full(setup->image_fd, NULL, FS_NOCOW_FL|FS_NOCOMP_FL, FS_NOCOW_FL|FS_NOCOMP_FL, NULL, NULL, CHATTR_FALLBACK_BITWISE);
|
||||
if (r < 0 && r != -ENOANO) /* ENOANO → some bits didn't work; which we skip logging about because chattr_full() already debug logs about those flags */
|
||||
log_full_errno(ERRNO_IS_NOT_SUPPORTED(r) ? LOG_DEBUG : LOG_WARNING, r,
|
||||
log_full_errno(ERRNO_IS_IOCTL_NOT_SUPPORTED(r) ? LOG_DEBUG : LOG_WARNING, r,
|
||||
"Failed to set file attributes on %s, ignoring: %m", setup->temporary_image_path);
|
||||
|
||||
r = calculate_initial_image_size(h, setup->image_fd, fstype, &host_size);
|
||||
|
||||
@@ -137,7 +137,7 @@ int action_setup_keys(void) {
|
||||
|
||||
r = chattr_secret(fd, CHATTR_WARN_UNSUPPORTED_FLAGS);
|
||||
if (r < 0)
|
||||
log_full_errno(ERRNO_IS_NOT_SUPPORTED(r) || arg_quiet ? LOG_DEBUG : LOG_WARNING,
|
||||
log_full_errno(ERRNO_IS_IOCTL_NOT_SUPPORTED(r) || arg_quiet ? LOG_DEBUG : LOG_WARNING,
|
||||
r, "Failed to set file attributes on a temporary file for '%s', ignoring: %m", path);
|
||||
|
||||
struct FSSHeader h = {
|
||||
|
||||
@@ -4368,7 +4368,7 @@ static int prepare_temporary_file(Context *context, PartitionTarget *t, uint64_t
|
||||
|
||||
if (FLAGS_SET(attrs, FS_NOCOW_FL)) {
|
||||
r = chattr_fd(fd, FS_NOCOW_FL, FS_NOCOW_FL);
|
||||
if (r < 0 && !ERRNO_IS_NOT_SUPPORTED(r))
|
||||
if (r < 0 && !ERRNO_IS_IOCTL_NOT_SUPPORTED(r))
|
||||
return log_error_errno(r, "Failed to disable copy-on-write on %s: %m", temp);
|
||||
}
|
||||
|
||||
|
||||
@@ -774,7 +774,7 @@ static int prepare_nocow(int fdf, const char *from, int fdt, unsigned *chattr_ma
|
||||
return 0;
|
||||
|
||||
r = read_attr_at(fdf, from, &attrs);
|
||||
if (r < 0 && !ERRNO_IS_NOT_SUPPORTED(r) && r != -ELOOP) /* If the source is a symlink we get ELOOP */
|
||||
if (r < 0 && !ERRNO_IS_IOCTL_NOT_SUPPORTED(r) && r != -ELOOP) /* If the source is a symlink we get ELOOP */
|
||||
return r;
|
||||
|
||||
if (FLAGS_SET(attrs, FS_NOCOW_FL)) {
|
||||
|
||||
@@ -232,7 +232,7 @@ int import_set_nocow_and_log(int fd, const char *path) {
|
||||
r = chattr_fd(fd, FS_NOCOW_FL, FS_NOCOW_FL);
|
||||
if (r < 0)
|
||||
return log_full_errno(
|
||||
ERRNO_IS_NOT_SUPPORTED(r) ? LOG_DEBUG : LOG_WARNING,
|
||||
ERRNO_IS_IOCTL_NOT_SUPPORTED(r) ? LOG_DEBUG : LOG_WARNING,
|
||||
r, "Failed to set file attributes on %s: %m", path);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1653,7 +1653,7 @@ static int fd_set_attribute(
|
||||
"previous=0x%08x, current=0x%08x, expected=0x%08x, ignoring.",
|
||||
path, previous, current, (previous & ~item->attribute_mask) | (f & item->attribute_mask));
|
||||
else if (r < 0)
|
||||
log_full_errno(ERRNO_IS_NOT_SUPPORTED(r) ? LOG_DEBUG : LOG_WARNING, r,
|
||||
log_full_errno(ERRNO_IS_IOCTL_NOT_SUPPORTED(r) ? LOG_DEBUG : LOG_WARNING, r,
|
||||
"Cannot set file attributes for '%s', value=0x%08x, mask=0x%08x, ignoring: %m",
|
||||
path, item->attribute_value, item->attribute_mask);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user