[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 3/6] fts: introduce MIN_DIR_NLINK
From: |
Paul Eggert |
Subject: |
[PATCH 3/6] fts: introduce MIN_DIR_NLINK |
Date: |
Tue, 25 Jul 2017 00:28:03 -0700 |
* lib/fts.c (MIN_DIR_NLINK): New constant.
Use it instead of 2, whenever we are talking about link counts.
---
ChangeLog | 4 ++++
lib/fts.c | 19 ++++++++++++++-----
2 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index da1fda1ad..7f532d411 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2017-07-24 Paul Eggert <address@hidden>
+ fts: introduce MIN_DIR_NLINK
+ * lib/fts.c (MIN_DIR_NLINK): New constant.
+ Use it instead of 2, whenever we are talking about link counts.
+
fts: nlink_t signedness fixups
* lib/fts.c (fts_open): Set rootparent n_dirs_remaining to -1
so that root need not be a special case later.
diff --git a/lib/fts.c b/lib/fts.c
index d5fc051a0..95d646c1f 100644
--- a/lib/fts.c
+++ b/lib/fts.c
@@ -666,6 +666,12 @@ fts_close (FTS *sp)
return (0);
}
+/* Minimum link count of a traditional Unix directory. When leaf
+ optimization is OK and MIN_DIR_NLINK <= st_nlink, then st_nlink is
+ an upper bound on the number of subdirectories (counting "." and
+ ".."). */
+enum { MIN_DIR_NLINK = 2 };
+
#if defined __linux__ \
&& HAVE_SYS_VFS_H && HAVE_FSTATFS && HAVE_STRUCT_STATFS_F_TYPE
@@ -712,8 +718,11 @@ dirent_inode_sort_may_be_useful (int dir_fd)
}
/* Given a file descriptor DIR_FD open on a directory D,
- return true if it is valid to apply the leaf-optimization
- technique of counting directories in D via stat.st_nlink. */
+ return true if it is both useful and valid to apply leaf optimization.
+ The optimization is useful only for file systems that lack usable
+ dirent.d_type info. The optimization is valid if an st_nlink value
+ of at least MIN_DIR_NLINK is an upper bound on the number of
+ subdirectories of D, counting "." and ".." as subdirectories. */
static bool
leaf_optimization_applies (int dir_fd)
{
@@ -1389,7 +1398,7 @@ fts_build (register FTS *sp, int type)
nostat = false;
} else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
nlinks = (cur->fts_statp->st_nlink
- - (ISSET(FTS_SEEDOT) ? 0 : 2));
+ - (ISSET (FTS_SEEDOT) ? 0 : MIN_DIR_NLINK));
nostat = true;
} else {
nlinks = -1;
@@ -1834,10 +1843,10 @@ err: memset(sbp, 0, sizeof(struct stat));
if (S_ISDIR(sbp->st_mode)) {
p->fts_n_dirs_remaining
- = ((sbp->st_nlink < 2
+ = ((sbp->st_nlink < MIN_DIR_NLINK
|| p->fts_level <= FTS_ROOTLEVEL)
? -1
- : sbp->st_nlink - (ISSET (FTS_SEEDOT) ? 0 : 2));
+ : sbp->st_nlink - (ISSET (FTS_SEEDOT) ? 0 :
MIN_DIR_NLINK));
if (ISDOT(p->fts_name)) {
/* Command-line "." and ".." are real directories. */
return (p->fts_level == FTS_ROOTLEVEL ? FTS_D :
FTS_DOT);
--
2.13.3