为什么“find”如此喜欢“stat”或“fstat”?

为什么“find”如此喜欢“stat”或“fstat”?

我试图/usr/bin/find在不做任何事情的情况下展示一些有意义的东西stat,到目前为止还没有任何有用的结果。如果我强行抑制stat, find 根本不会下降到子目录中。

正如系统调用手册页getdents所说,那里有d_type字段,所以find应该已经有一些决策所需的信息。

为什么需要stat不管-L-H或任何选择。

答案1

使用来源,卢克!

在 GNUfind源代码中(我正在查看版本 4.2.2),遍历目录树的代码位于gnulib/lib/fts.c.第 1123 行有以下注释:

记录 fts_read 与此条目的关系。在许多情况下,它只会简单地对其进行 fts_stat,但我们可以利用任何 d_type 信息来优化不必要的 stat 调用。即,如果 FTS_NOSTAT 有效并且我们没有遵循符号链接(FTS_PHYSICAL)并且 d_type 指示这是不是一个目录,那么我们根本不需要统计它。如果它一个目录,然后(当前)我们无论如何都要对其进行统计,以便获取设备和索引节点号。有一天,我们可能也会针对已知 d_ino 有效的目录进行优化。

所以他们想到了你描述的优化,但是没有实现。

答案2

引用的手册页盖登茨是 Linux 特定的,并不适用于所有文件系统类型(例如,手册页没有提到procfs或者nfs),而 GNU寻找不是特定于平台的(它的手册页提到了 SELinux,这可以说是一个需要考虑的有用功能)。它可以也针对这种特殊情况进行优化。

即使该功能可用,手册页也建议:

所有应用程序必须正确处理退货DT_UNKNOWN

也就是说,如果可用的信息可能是有用的,但不能保证它会存在。

由于存在所有这些缺点,开发人员find可能认为没有必要进行这种优化。有动力的用户可以深入研究源代码以了解如何执行此操作并提出合适的 ifdef 更改。

@内特·埃尔德雷奇注意到有人开始了朝这个方向。手册find中指出7.2 d_type优化

启用此功能后,find 会利用以下事实:在某些系统上 readdir 将返回 struct dirent 中的文件类型。

该功能是首先提到的

2005-01-17  James Youngman  <[email protected]>
    * configure.in, find/defs.h, find/find.c, find/parser.c, find/pred.c, find/tree.c, find/util.c:
    Implemented d_type optimisation but not working correctly, so currently disabled

后来,是修改为使用 gnulib支持这一点:

2010-04-08  James Youngman  <[email protected]>

    Adopt the use of the gnulib module d-type.
    * import-gnulib.config (modules): Import the d-type module.
    * configure.ac: Remove old struct dirent.d_type detection logic
    (since we now use the gnulib macro from the d-type module for
    this).

顺便说一句,4.2.2 版本相当旧(可能是拼写错误):4.2.3日期可以追溯到 2004 年,并且早于这些变更日志条目。 git 中当前的发布标签是4.5.14(2014 年中)。

无论优化的状态如何d_type,开发人员都对减少对stat.来自的注释4.5.4(2009-03-10) 例如说:

如果我们已经从目录中读取了此信息,ftsfind 可执行文件现在还可以避免调用 stat() 函数来发现文件的索引节点号。这确实提供了加速,但仅限于有限的命令集,例如“find . -inum 4001”。此修复在下面列出为 bug #24342。

总结:OP问

为什么需要统计数据而不管 -L、-H 或任何选项。

原因是它是一种特殊情况,使其无缝工作很麻烦,而不是stat适用于所有find可能需要它的场景,并且需要时间来做到这一点。

相关内容