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:
Daan De Meyer
2025-05-26 21:59:08 +02:00
parent 8cf13c8752
commit f1ee656d4d
8 changed files with 17 additions and 18 deletions
+10 -11
View File
@@ -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) {
+1 -1
View File
@@ -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;
}