From: Jim Meyering Date: Thu, 3 Sep 2009 13:15:09 +0000 (+0200) Subject: rm: improve efficiency of rm -r (without -f) from O(N^2) to O(N) X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0f3f7d495c82b8b07945830314456ee0bfe3bf73;p=thirdparty%2Fcoreutils.git rm: improve efficiency of rm -r (without -f) from O(N^2) to O(N) where N is the depth of the deepest hierarchy rm is processing. * src/remove.c (write_protected_non_symlink): Use faccessat to avoid O(N)-per-entry cost of calling euidaccess. * m4/jm-macros.m4 (coreutils_MACROS): Check for faccessat. --- diff --git a/m4/jm-macros.m4 b/m4/jm-macros.m4 index f4d43f1dda..75ee75e2d3 100644 --- a/m4/jm-macros.m4 +++ b/m4/jm-macros.m4 @@ -92,6 +92,9 @@ AC_DEFUN([coreutils_MACROS], # for cp.c AC_CHECK_FUNCS_ONCE([utimensat]) + # for remove.c + AC_CHECK_FUNCS_ONCE([faccessat]) + dnl This can't use AC_REQUIRE; I'm not quite sure why. cu_PREREQ_STAT_PROG diff --git a/src/remove.c b/src/remove.c index 32f67a1816..2db3859092 100644 --- a/src/remove.c +++ b/src/remove.c @@ -172,6 +172,13 @@ write_protected_non_symlink (int fd_cwd, mess up with long file names). */ { + /* Use faccessat if possible, so as to avoid the expense + of processing an N-component name. */ +#if HAVE_FACCESSAT && AT_EACCESS + if (faccessat (fd_cwd, file, W_OK, AT_EACCESS) == 0) + return 0; +#endif + /* This implements #5: */ size_t file_name_len = strlen (full_name);