On 2023-04-28 13:38, Ondrej Valousek wrote:
On newer systems like Fedora 39, we can't distinguish from the
getxattr(,XATTR_NAME_POSIX_ACL_*,,)
which filesystem we are on. The call return either success or ENODATA.
Does getxattr (name, XATTR_NAME_NFSV4_ACL, xattr, sizeof xattr) also
have this problem on Fedora 39? If not, perhaps we should instead do the
NFSv4 call first, to save the need for the "POSIX" getxattr call when
the file system supports NFSv4. Something like the attached, perhaps?From 278f85791e55199616341977926127bdf4bd619f Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Fri, 28 Apr 2023 20:03:49 -0700
Subject: [PATCH] file-has-acl: port to Fedora 39
On Fedora 39, getxattr (name, XATTR_NAME_POSIX_ACL_ACCESS, NULL, 0)
never fails with ENOTSUP. Problem reported by Ondrej Valousek in:
https://lists.gnu.org/r/bug-gnulib/2023-04/msg00228.html
* lib/file-has-acl.c (file_has_acl): Try NFSv4 ACLs first,
and fall back on POSIX ACLs only if the former are absent.
This saves us a syscall on Fedora 39, where
---
ChangeLog | 10 +++++++
lib/file-has-acl.c | 74 ++++++++++++++++++++++------------------------
2 files changed, 46 insertions(+), 38 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 3932a30ae1..e027b70b6f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2023-04-28 Paul Eggert <egg...@cs.ucla.edu>
+
+ file-has-acl: port to Fedora 39
+ On Fedora 39, getxattr (name, XATTR_NAME_POSIX_ACL_ACCESS, NULL, 0)
+ never fails with ENOTSUP. Problem reported by Ondrej Valousek in:
+ https://lists.gnu.org/r/bug-gnulib/2023-04/msg00228.html
+ * lib/file-has-acl.c (file_has_acl): Try NFSv4 ACLs first,
+ and fall back on POSIX ACLs only if the former are absent.
+ This saves us a syscall on Fedora 39, where
+
2023-04-27 Bruno Haible <br...@clisp.org>
localeconv: Work around a mingw bug.
diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c
index b31a2ea252..525a29972c 100644
--- a/lib/file-has-acl.c
+++ b/lib/file-has-acl.c
@@ -142,50 +142,48 @@ file_has_acl (char const *name, struct stat const *sb)
ssize_t ret;
int initial_errno = errno;
- ret = getxattr (name, XATTR_NAME_POSIX_ACL_ACCESS, NULL, 0);
- if (ret < 0 && errno == ENODATA)
- ret = 0;
- else if (ret > 0)
- return 1;
-
- if (ret == 0 && S_ISDIR (sb->st_mode))
- {
- ret = getxattr (name, XATTR_NAME_POSIX_ACL_DEFAULT, NULL, 0);
- if (ret < 0 && errno == ENODATA)
- ret = 0;
- else if (ret > 0)
- return 1;
- }
-
+ /* Check for NFSv4 ACLs. The max length of a trivial
+ ACL is 6 words for owner, 6 for group, 7 for everyone,
+ all times 2 because there are both allow and deny ACEs.
+ There are 6 words for owner because of type, flag, mask,
+ wholen, "OWNER@"+pad and similarly for group; everyone is
+ another word to hold "EVERYONE@". */
+ uint32_t xattr[2 * (6 + 6 + 7)];
+
+ ret = getxattr (name, XATTR_NAME_NFSV4_ACL, xattr, sizeof xattr);
if (ret < 0)
- {
- /* Check for NFSv4 ACLs. The max length of a trivial
- ACL is 6 words for owner, 6 for group, 7 for everyone,
- all times 2 because there are both allow and deny ACEs.
- There are 6 words for owner because of type, flag, mask,
- wholen, "OWNER@"+pad and similarly for group; everyone is
- another word to hold "EVERYONE@". */
- uint32_t xattr[2 * (6 + 6 + 7)];
-
- ret = getxattr (name, XATTR_NAME_NFSV4_ACL, xattr, sizeof xattr);
- if (ret < 0)
- switch (errno)
+ switch (errno)
+ {
+ case ENODATA: return 0;
+ case ERANGE: return 1; /* This NFSv4 ACL must be nontrivial. */
+ case EOPNOTSUPP:
+ ret = getxattr (name, XATTR_NAME_POSIX_ACL_ACCESS, NULL, 0);
+ if (ret < 0 && errno == ENODATA)
+ ret = 0;
+ else if (ret > 0)
+ return 1;
+ if (ret == 0 && S_ISDIR (sb->st_mode))
{
- case ENODATA: return 0;
- case ERANGE : return 1; /* ACL must be nontrivial. */
+ ret = getxattr (name, XATTR_NAME_POSIX_ACL_DEFAULT, NULL, 0);
+ if (ret < 0 && errno == ENODATA)
+ ret = 0;
+ else if (ret > 0)
+ return 1;
}
- else
+ break;
+ }
+ else
+ {
+ /* It looks like a trivial NFSv4 ACL; investigate further. */
+ ret = acl_nfs4_nontrivial (xattr, ret);
+ if (ret < 0)
{
- /* It looks like a trivial ACL, but investigate further. */
- ret = acl_nfs4_nontrivial (xattr, ret);
- if (ret < 0)
- {
- errno = EINVAL;
- return ret;
- }
- errno = initial_errno;
+ errno = EINVAL;
+ return ret;
}
+ errno = initial_errno;
}
+
if (ret < 0)
return - acl_errno_valid (errno);
return ret;
--
2.39.2