|
Kamil Dudka |
dd90a0 |
From 42b0e609390e62a900c0d73de60282c8b0f15121 Mon Sep 17 00:00:00 2001
|
|
Kamil Dudka |
dd90a0 |
From: Paul Eggert <eggert@cs.ucla.edu>
|
|
Kamil Dudka |
dd90a0 |
Date: Thu, 5 Apr 2018 08:48:01 -0700
|
|
Kamil Dudka |
dd90a0 |
Subject: [PATCH 1/2] fts: treat CIFS like NFS
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
Problem reported by Kamil Dudka in:
|
|
Kamil Dudka |
dd90a0 |
https://lists.gnu.org/r/bug-gnulib/2018-04/msg00015.html
|
|
Kamil Dudka |
dd90a0 |
* lib/fts.c (S_MAGIC_CIFS): New macro.
|
|
Kamil Dudka |
dd90a0 |
(dirent_inode_sort_may_be_useful, leaf_optimization):
|
|
Kamil Dudka |
dd90a0 |
Treat CIFS like NFS.
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
Upstream-commit: 2e53df541a30d438859087ed4b5a396e04697b9b
|
|
Kamil Dudka |
dd90a0 |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
Kamil Dudka |
dd90a0 |
---
|
|
Kamil Dudka |
dd90a0 |
lib/fts.c | 8 +++++++-
|
|
Kamil Dudka |
dd90a0 |
1 file changed, 7 insertions(+), 1 deletion(-)
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
diff --git a/lib/fts.c b/lib/fts.c
|
|
Kamil Dudka |
dd90a0 |
index 8f2595d..0689da6 100644
|
|
Kamil Dudka |
dd90a0 |
--- a/lib/fts.c
|
|
Kamil Dudka |
dd90a0 |
+++ b/lib/fts.c
|
|
Kamil Dudka |
dd90a0 |
@@ -685,6 +685,7 @@ enum leaf_optimization
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
/* Linux-specific constants from coreutils' src/fs.h */
|
|
Kamil Dudka |
dd90a0 |
# define S_MAGIC_AFS 0x5346414F
|
|
Kamil Dudka |
dd90a0 |
+# define S_MAGIC_CIFS 0xFF534D42
|
|
Kamil Dudka |
dd90a0 |
# define S_MAGIC_NFS 0x6969
|
|
Kamil Dudka |
dd90a0 |
# define S_MAGIC_PROC 0x9FA0
|
|
Kamil Dudka |
dd90a0 |
# define S_MAGIC_REISERFS 0x52654973
|
|
Kamil Dudka |
dd90a0 |
@@ -792,8 +793,9 @@ dirent_inode_sort_may_be_useful (FTSENT const *p)
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
switch (filesystem_type (p))
|
|
Kamil Dudka |
dd90a0 |
{
|
|
Kamil Dudka |
dd90a0 |
- case S_MAGIC_TMPFS:
|
|
Kamil Dudka |
dd90a0 |
+ case S_MAGIC_CIFS:
|
|
Kamil Dudka |
dd90a0 |
case S_MAGIC_NFS:
|
|
Kamil Dudka |
dd90a0 |
+ case S_MAGIC_TMPFS:
|
|
Kamil Dudka |
dd90a0 |
/* On a file system of any of these types, sorting
|
|
Kamil Dudka |
dd90a0 |
is unnecessary, and hence wasteful. */
|
|
Kamil Dudka |
dd90a0 |
return false;
|
|
Kamil Dudka |
dd90a0 |
@@ -827,6 +829,10 @@ leaf_optimization (FTSENT const *p)
|
|
Kamil Dudka |
dd90a0 |
/* Although AFS mount points are not counted in st_nlink, they
|
|
Kamil Dudka |
dd90a0 |
act like directories. See <https://bugs.debian.org/143111>. */
|
|
Kamil Dudka |
dd90a0 |
FALLTHROUGH;
|
|
Kamil Dudka |
dd90a0 |
+ case S_MAGIC_CIFS:
|
|
Kamil Dudka |
dd90a0 |
+ /* Leaf optimization causes 'find' to abort. See
|
|
Kamil Dudka |
dd90a0 |
+ <https://lists.gnu.org/r/bug-gnulib/2018-04/msg00015.html>. */
|
|
Kamil Dudka |
dd90a0 |
+ FALLTHROUGH;
|
|
Kamil Dudka |
dd90a0 |
case S_MAGIC_NFS:
|
|
Kamil Dudka |
dd90a0 |
/* NFS provides usable dirent.d_type but not necessarily for all entries
|
|
Kamil Dudka |
dd90a0 |
of large directories, so as per <https://bugzilla.redhat.com/1252549>
|
|
Kamil Dudka |
dd90a0 |
--
|
|
Kamil Dudka |
dd90a0 |
2.14.3
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
From bf96f62507931eb296c5b16d7e46c141ad505a1f Mon Sep 17 00:00:00 2001
|
|
Kamil Dudka |
dd90a0 |
From: Paul Eggert <eggert@cs.ucla.edu>
|
|
Kamil Dudka |
dd90a0 |
Date: Wed, 11 Apr 2018 12:50:35 -0700
|
|
Kamil Dudka |
dd90a0 |
Subject: [PATCH 2/2] fts: fix bug in find across filesystems
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
This fixes a bug I introduced last summer.
|
|
Kamil Dudka |
dd90a0 |
Problem reported by Kamil Dudka in:
|
|
Kamil Dudka |
dd90a0 |
https://lists.gnu.org/r/bug-gnulib/2018-04/msg00033.html
|
|
Kamil Dudka |
dd90a0 |
* lib/fts.c (filesystem_type, dirent_inode_sort_may_be_useful)
|
|
Kamil Dudka |
dd90a0 |
(leaf_optimization):
|
|
Kamil Dudka |
dd90a0 |
New arg for file descriptor. All callers changed.
|
|
Kamil Dudka |
dd90a0 |
(fts_build): Check for whether inodes should be sorted
|
|
Kamil Dudka |
dd90a0 |
before closing the directory.
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
Upstream-commit: 81b8c0d3be98f5a77403599de3d06329b3e7673e
|
|
Kamil Dudka |
dd90a0 |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
Kamil Dudka |
dd90a0 |
---
|
|
Kamil Dudka |
dd90a0 |
lib/fts.c | 55 +++++++++++++++++++++++++++++++------------------------
|
|
Kamil Dudka |
dd90a0 |
1 file changed, 31 insertions(+), 24 deletions(-)
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
diff --git a/lib/fts.c b/lib/fts.c
|
|
Kamil Dudka |
dd90a0 |
index 0689da6..6420ba1 100644
|
|
Kamil Dudka |
dd90a0 |
--- a/lib/fts.c
|
|
Kamil Dudka |
dd90a0 |
+++ b/lib/fts.c
|
|
Kamil Dudka |
dd90a0 |
@@ -726,11 +726,12 @@ dev_type_compare (void const *x, void const *y)
|
|
Kamil Dudka |
dd90a0 |
return ax->st_dev == ay->st_dev;
|
|
Kamil Dudka |
dd90a0 |
}
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
-/* Return the file system type of P, or 0 if not known.
|
|
Kamil Dudka |
dd90a0 |
+/* Return the file system type of P with file descriptor FD, or 0 if not known.
|
|
Kamil Dudka |
dd90a0 |
+ If FD is negative, P's file descriptor is unavailable.
|
|
Kamil Dudka |
dd90a0 |
Try to cache known values. */
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
static fsword
|
|
Kamil Dudka |
dd90a0 |
-filesystem_type (FTSENT const *p)
|
|
Kamil Dudka |
dd90a0 |
+filesystem_type (FTSENT const *p, int fd)
|
|
Kamil Dudka |
dd90a0 |
{
|
|
Kamil Dudka |
dd90a0 |
FTS *sp = p->fts_fts;
|
|
Kamil Dudka |
dd90a0 |
Hash_table *h = sp->fts_leaf_optimization_works_ht;
|
|
Kamil Dudka |
dd90a0 |
@@ -756,7 +757,7 @@ filesystem_type (FTSENT const *p)
|
|
Kamil Dudka |
dd90a0 |
}
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
/* Look-up failed. Query directly and cache the result. */
|
|
Kamil Dudka |
dd90a0 |
- if (fstatfs (p->fts_fts->fts_cwd_fd, &fs_buf) != 0)
|
|
Kamil Dudka |
dd90a0 |
+ if (fd < 0 || fstatfs (fd, &fs_buf) != 0)
|
|
Kamil Dudka |
dd90a0 |
return 0;
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
if (h)
|
|
Kamil Dudka |
dd90a0 |
@@ -778,12 +779,12 @@ filesystem_type (FTSENT const *p)
|
|
Kamil Dudka |
dd90a0 |
return fs_buf.f_type;
|
|
Kamil Dudka |
dd90a0 |
}
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
-/* Return false if it is easy to determine the file system type of the
|
|
Kamil Dudka |
dd90a0 |
- directory P, and sorting dirents on inode numbers is known not to
|
|
Kamil Dudka |
dd90a0 |
- improve traversal performance with that type of file system.
|
|
Kamil Dudka |
dd90a0 |
- Otherwise, return true. */
|
|
Kamil Dudka |
dd90a0 |
+/* Return true if sorting dirents on inode numbers is known to improve
|
|
Kamil Dudka |
dd90a0 |
+ traversal performance for the directory P with descriptor DIR_FD.
|
|
Kamil Dudka |
dd90a0 |
+ Return false otherwise. When in doubt, return true.
|
|
Kamil Dudka |
dd90a0 |
+ DIR_FD is negative if unavailable. */
|
|
Kamil Dudka |
dd90a0 |
static bool
|
|
Kamil Dudka |
dd90a0 |
-dirent_inode_sort_may_be_useful (FTSENT const *p)
|
|
Kamil Dudka |
dd90a0 |
+dirent_inode_sort_may_be_useful (FTSENT const *p, int dir_fd)
|
|
Kamil Dudka |
dd90a0 |
{
|
|
Kamil Dudka |
dd90a0 |
/* Skip the sort only if we can determine efficiently
|
|
Kamil Dudka |
dd90a0 |
that skipping it is the right thing to do.
|
|
Kamil Dudka |
dd90a0 |
@@ -791,7 +792,7 @@ dirent_inode_sort_may_be_useful (FTSENT const *p)
|
|
Kamil Dudka |
dd90a0 |
while the cost of *not* performing it can be O(N^2) with
|
|
Kamil Dudka |
dd90a0 |
a very large constant. */
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
- switch (filesystem_type (p))
|
|
Kamil Dudka |
dd90a0 |
+ switch (filesystem_type (p, dir_fd))
|
|
Kamil Dudka |
dd90a0 |
{
|
|
Kamil Dudka |
dd90a0 |
case S_MAGIC_CIFS:
|
|
Kamil Dudka |
dd90a0 |
case S_MAGIC_NFS:
|
|
Kamil Dudka |
dd90a0 |
@@ -805,16 +806,17 @@ dirent_inode_sort_may_be_useful (FTSENT const *p)
|
|
Kamil Dudka |
dd90a0 |
}
|
|
Kamil Dudka |
dd90a0 |
}
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
-/* Given an FTS entry P for a directory D,
|
|
Kamil Dudka |
dd90a0 |
+/* Given an FTS entry P for a directory with descriptor DIR_FD,
|
|
Kamil Dudka |
dd90a0 |
return true if it is both useful and valid to apply leaf optimization.
|
|
Kamil Dudka |
dd90a0 |
The optimization is useful only for file systems that lack usable
|
|
Kamil Dudka |
dd90a0 |
dirent.d_type info. The optimization is valid if an st_nlink value
|
|
Kamil Dudka |
dd90a0 |
of at least MIN_DIR_NLINK is an upper bound on the number of
|
|
Kamil Dudka |
dd90a0 |
- subdirectories of D, counting "." and ".." as subdirectories. */
|
|
Kamil Dudka |
dd90a0 |
+ subdirectories of D, counting "." and ".." as subdirectories.
|
|
Kamil Dudka |
dd90a0 |
+ DIR_FD is negative if unavailable. */
|
|
Kamil Dudka |
dd90a0 |
static enum leaf_optimization
|
|
Kamil Dudka |
dd90a0 |
-leaf_optimization (FTSENT const *p)
|
|
Kamil Dudka |
dd90a0 |
+leaf_optimization (FTSENT const *p, int dir_fd)
|
|
Kamil Dudka |
dd90a0 |
{
|
|
Kamil Dudka |
dd90a0 |
- switch (filesystem_type (p))
|
|
Kamil Dudka |
dd90a0 |
+ switch (filesystem_type (p, dir_fd))
|
|
Kamil Dudka |
dd90a0 |
{
|
|
Kamil Dudka |
dd90a0 |
/* List here the file system types that may lack usable dirent.d_type
|
|
Kamil Dudka |
dd90a0 |
info, yet for which the optimization does apply. */
|
|
Kamil Dudka |
dd90a0 |
@@ -851,12 +853,13 @@ leaf_optimization (FTSENT const *p)
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
#else
|
|
Kamil Dudka |
dd90a0 |
static bool
|
|
Kamil Dudka |
dd90a0 |
-dirent_inode_sort_may_be_useful (FTSENT const *p _GL_UNUSED)
|
|
Kamil Dudka |
dd90a0 |
+dirent_inode_sort_may_be_useful (FTSENT const *p _GL_UNUSED,
|
|
Kamil Dudka |
dd90a0 |
+ int dir_fd _GL_UNUSED)
|
|
Kamil Dudka |
dd90a0 |
{
|
|
Kamil Dudka |
dd90a0 |
return true;
|
|
Kamil Dudka |
dd90a0 |
}
|
|
Kamil Dudka |
dd90a0 |
static enum leaf_optimization
|
|
Kamil Dudka |
dd90a0 |
-leaf_optimization (FTSENT const *p _GL_UNUSED)
|
|
Kamil Dudka |
dd90a0 |
+leaf_optimization (FTSENT const *p _GL_UNUSED, int dir_fd _GL_UNUSED)
|
|
Kamil Dudka |
dd90a0 |
{
|
|
Kamil Dudka |
dd90a0 |
return NO_LEAF_OPTIMIZATION;
|
|
Kamil Dudka |
dd90a0 |
}
|
|
Kamil Dudka |
dd90a0 |
@@ -1050,7 +1053,7 @@ check_for_dir:
|
|
Kamil Dudka |
dd90a0 |
if (parent->fts_n_dirs_remaining == 0
|
|
Kamil Dudka |
dd90a0 |
&& ISSET(FTS_NOSTAT)
|
|
Kamil Dudka |
dd90a0 |
&& ISSET(FTS_PHYSICAL)
|
|
Kamil Dudka |
dd90a0 |
- && (leaf_optimization (parent)
|
|
Kamil Dudka |
dd90a0 |
+ && (leaf_optimization (parent, sp->fts_cwd_fd)
|
|
Kamil Dudka |
dd90a0 |
== NOSTAT_LEAF_OPTIMIZATION))
|
|
Kamil Dudka |
dd90a0 |
{
|
|
Kamil Dudka |
dd90a0 |
/* nothing more needed */
|
|
Kamil Dudka |
dd90a0 |
@@ -1335,6 +1338,7 @@ fts_build (register FTS *sp, int type)
|
|
Kamil Dudka |
dd90a0 |
int dir_fd;
|
|
Kamil Dudka |
dd90a0 |
FTSENT *cur = sp->fts_cur;
|
|
Kamil Dudka |
dd90a0 |
bool continue_readdir = !!cur->fts_dirp;
|
|
Kamil Dudka |
dd90a0 |
+ bool sort_by_inode = false;
|
|
Kamil Dudka |
dd90a0 |
size_t max_entries;
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
/* When cur->fts_dirp is non-NULL, that means we should
|
|
Kamil Dudka |
dd90a0 |
@@ -1428,7 +1432,7 @@ fts_build (register FTS *sp, int type)
|
|
Kamil Dudka |
dd90a0 |
&& ! (ISSET (FTS_NOSTAT) && ISSET (FTS_PHYSICAL)
|
|
Kamil Dudka |
dd90a0 |
&& ! ISSET (FTS_SEEDOT)
|
|
Kamil Dudka |
dd90a0 |
&& cur->fts_statp->st_nlink == MIN_DIR_NLINK
|
|
Kamil Dudka |
dd90a0 |
- && (leaf_optimization (cur)
|
|
Kamil Dudka |
dd90a0 |
+ && (leaf_optimization (cur, dir_fd)
|
|
Kamil Dudka |
dd90a0 |
!= NO_LEAF_OPTIMIZATION)));
|
|
Kamil Dudka |
dd90a0 |
if (descend || type == BREAD)
|
|
Kamil Dudka |
dd90a0 |
{
|
|
Kamil Dudka |
dd90a0 |
@@ -1589,6 +1593,15 @@ mem1: saved_errno = errno;
|
|
Kamil Dudka |
dd90a0 |
tail->fts_link = p;
|
|
Kamil Dudka |
dd90a0 |
tail = p;
|
|
Kamil Dudka |
dd90a0 |
}
|
|
Kamil Dudka |
dd90a0 |
+
|
|
Kamil Dudka |
dd90a0 |
+ /* If there are many entries, no sorting function has been
|
|
Kamil Dudka |
dd90a0 |
+ specified, and this file system is of a type that may be
|
|
Kamil Dudka |
dd90a0 |
+ slow with a large number of entries, arrange to sort the
|
|
Kamil Dudka |
dd90a0 |
+ directory entries on increasing inode numbers. */
|
|
Kamil Dudka |
dd90a0 |
+ if (nitems == _FTS_INODE_SORT_DIR_ENTRIES_THRESHOLD
|
|
Kamil Dudka |
dd90a0 |
+ && !sp->fts_compar)
|
|
Kamil Dudka |
dd90a0 |
+ sort_by_inode = dirent_inode_sort_may_be_useful (cur, dir_fd);
|
|
Kamil Dudka |
dd90a0 |
+
|
|
Kamil Dudka |
dd90a0 |
++nitems;
|
|
Kamil Dudka |
dd90a0 |
if (max_entries <= nitems) {
|
|
Kamil Dudka |
dd90a0 |
/* When there are too many dir entries, leave
|
|
Kamil Dudka |
dd90a0 |
@@ -1646,13 +1659,7 @@ mem1: saved_errno = errno;
|
|
Kamil Dudka |
dd90a0 |
return (NULL);
|
|
Kamil Dudka |
dd90a0 |
}
|
|
Kamil Dudka |
dd90a0 |
|
|
Kamil Dudka |
dd90a0 |
- /* If there are many entries, no sorting function has been specified,
|
|
Kamil Dudka |
dd90a0 |
- and this file system is of a type that may be slow with a large
|
|
Kamil Dudka |
dd90a0 |
- number of entries, then sort the directory entries on increasing
|
|
Kamil Dudka |
dd90a0 |
- inode numbers. */
|
|
Kamil Dudka |
dd90a0 |
- if (nitems > _FTS_INODE_SORT_DIR_ENTRIES_THRESHOLD
|
|
Kamil Dudka |
dd90a0 |
- && !sp->fts_compar
|
|
Kamil Dudka |
dd90a0 |
- && dirent_inode_sort_may_be_useful (cur)) {
|
|
Kamil Dudka |
dd90a0 |
+ if (sort_by_inode) {
|
|
Kamil Dudka |
dd90a0 |
sp->fts_compar = fts_compare_ino;
|
|
Kamil Dudka |
dd90a0 |
head = fts_sort (sp, head, nitems);
|
|
Kamil Dudka |
dd90a0 |
sp->fts_compar = NULL;
|
|
Kamil Dudka |
dd90a0 |
--
|
|
Kamil Dudka |
dd90a0 |
2.14.3
|
|
Kamil Dudka |
dd90a0 |
|