Hello,

the attached patch allows ls(1) from coreutils to eliminate unnecessary calls 
of getxattr() and thus prevents it from triggerring unnecessary mounts while 
listing files.  The feature is enabled automatically whenever 
acl_extended_file_nofollow() is available at build-time.  See the following 
bug for more details:

https://bugzilla.redhat.com/692823

Thanks in advance for considering the patch!

Kamil
From 11097f2d5f8dd86cef9f0dbd71c2655377561f5e Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdu...@redhat.com>
Date: Wed, 6 Apr 2011 16:39:44 +0200
Subject: [PATCH] file-has-acl: use acl_extended_file_nofollow() if available

* lib/acl-internal.h (HAVE_ACL_EXTENDED_FILE): New macro.
(acl_extended_file): New macro.
* lib/file-has-acl.c (file_has_acl): Use acl_extended_file_nofollow().
* m4/acl.m4 (gl_FUNC_ACL): Check availability of
acl_extended_file_nofollow().
---
 ChangeLog          |    9 +++++++++
 lib/acl-internal.h |    6 ++++++
 lib/file-has-acl.c |    9 ++++++++-
 m4/acl.m4          |    2 +-
 4 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index eee9509..48f1d7a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2011-04-06  Kamil Dudka  <kdu...@redhat.com>
+
+	file-has-acl: use acl_extended_file_nofollow() if available
+	* lib/acl-internal.h (HAVE_ACL_EXTENDED_FILE): New macro.
+	(acl_extended_file): New macro.
+	* lib/file-has-acl.c (file_has_acl): Use acl_extended_file_nofollow().
+	* m4/acl.m4 (gl_FUNC_ACL): Check availability of
+	acl_extended_file_nofollow().
+
 2011-04-06  Paul Eggert  <egg...@cs.ucla.edu>
 
 	verify: use _Static_assert if available
diff --git a/lib/acl-internal.h b/lib/acl-internal.h
index 0eb11bc..f80af6d 100644
--- a/lib/acl-internal.h
+++ b/lib/acl-internal.h
@@ -124,6 +124,12 @@ rpl_acl_set_fd (int fd, acl_t acl)
 #  endif
 
 /* Linux-specific */
+#  ifndef HAVE_ACL_EXTENDED_FILE_NOFOLLOW
+#   define HAVE_ACL_EXTENDED_FILE_NOFOLLOW false
+#   define acl_extended_file(name) (-1)
+#  endif
+
+/* Linux-specific */
 #  ifndef HAVE_ACL_FROM_MODE
 #   define HAVE_ACL_FROM_MODE false
 #   define acl_from_mode(mode) (NULL)
diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c
index a815e4c..0688d8a 100644
--- a/lib/file-has-acl.c
+++ b/lib/file-has-acl.c
@@ -339,12 +339,19 @@ file_has_acl (char const *name, struct stat const *sb)
       /* Linux, FreeBSD, MacOS X, IRIX, Tru64 */
       int ret;
 
-      if (HAVE_ACL_EXTENDED_FILE) /* Linux */
+      if (HAVE_ACL_EXTENDED_FILE || HAVE_ACL_EXTENDED_FILE_NOFOLLOW) /* Linux */
         {
+#   if HAVE_ACL_EXTENDED_FILE_NOFOLLOW
+          /* acl_extended_file_nofollow() uses lgetxattr() in order to prevent
+             unnecessary mounts, but it returns the same result as we already
+             know the file is not a symbolic link at this point */
+          ret = acl_extended_file_nofollow (name);
+#   else
           /* On Linux, acl_extended_file is an optimized function: It only
              makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for
              ACL_TYPE_DEFAULT.  */
           ret = acl_extended_file (name);
+#   endif
         }
       else /* FreeBSD, MacOS X, IRIX, Tru64 */
         {
diff --git a/m4/acl.m4 b/m4/acl.m4
index a01382d..9c0f451 100644
--- a/m4/acl.m4
+++ b/m4/acl.m4
@@ -33,7 +33,7 @@ AC_DEFUN([gl_FUNC_ACL],
            AC_CHECK_FUNCS(
              [acl_get_file acl_get_fd acl_set_file acl_set_fd \
               acl_free acl_from_mode acl_from_text \
-              acl_delete_def_file acl_extended_file \
+              acl_delete_def_file acl_extended_file acl_extended_file_nofollow \
               acl_delete_fd_np acl_delete_file_np \
               acl_copy_ext_native acl_create_entry_np \
               acl_to_short_text acl_free_text])
-- 
1.7.4

Reply via email to