From: Daan De Meyer Date: Mon, 26 May 2025 14:11:06 +0000 (+0200) Subject: tree-wide: Handle EINVAL as not supported for chattr_xxx() X-Git-Tag: v258-rc1~490 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f1ee656d4d2c52eaf956772c4b30c9ae637bbaff;p=thirdparty%2Fsystemd.git 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 --- diff --git a/src/basic/chattr-util.c b/src/basic/chattr-util.c index 5786c12a3f8..70a0210f72b 100644 --- a/src/basic/chattr-util.c +++ b/src/basic/chattr-util.c @@ -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) { diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index 6c6b0059677..5db9572ba55 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -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; } diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c index dc510eb1f5f..e92e5e2eb9a 100644 --- a/src/home/homework-luks.c +++ b/src/home/homework-luks.c @@ -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); diff --git a/src/journal/journalctl-authenticate.c b/src/journal/journalctl-authenticate.c index 7b2d8714ad8..0728493e014 100644 --- a/src/journal/journalctl-authenticate.c +++ b/src/journal/journalctl-authenticate.c @@ -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 = { diff --git a/src/repart/repart.c b/src/repart/repart.c index ccc820ec515..89d4297d626 100644 --- a/src/repart/repart.c +++ b/src/repart/repart.c @@ -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); } diff --git a/src/shared/copy.c b/src/shared/copy.c index 08828856c0b..ca2325459d9 100644 --- a/src/shared/copy.c +++ b/src/shared/copy.c @@ -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)) { diff --git a/src/shared/import-util.c b/src/shared/import-util.c index 50794a86ba9..9c9a9d7e301 100644 --- a/src/shared/import-util.c +++ b/src/shared/import-util.c @@ -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; diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 3a3f8b1bfd2..5d51d9ae4fd 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -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); }