Linux 内核还没有接口来获取文件创建日期吗?

Linux 内核还没有接口来获取文件创建日期吗?

很长一段时间以来,Linux 并没有关心文件创建日期,因为它常用的文件系统都不支持它们。然而现在,两种常用的文件系统(NTFS 和 ext4)都记录文件创建日期。

stat然而,该命令仍然Birth: -在 ext4 文件系统上输出,即使我们可以看到 ext4 已使用debugfs -R 'stat <inode_number>' /dev/file_device.

当我研究这是为什么时,我看到其他人已经最近提交的关于它的错误报告,响应链接到上游问题它只是简单地指出“目前没有 Linux 内核接口来获取该信息 [文件创建日期]”。对我来说,这显然是值得注意的仍然stat这种情况,因为人们多年来一直要求显示此信息(并且stat确实输出一个Birth字段,即使它显然还不支持它!他们是否在预期中添加了它?)

那么,目前是否仍然没有 Linux 内核接口来获取文件创建日期?是否有计划实现这一点?

答案1

编辑:好消息,statx()已合并,因此应该在版本 4.11 中可用。


xstat() 工作(目前为 statx())于 2016 年进行了修订。

这次的过程更加严格(减少自行车脱落,同意放弃有争议的属性,因为它们可以在以后添加)。不幸的是,仍然有人对确切的界面提出异议,而且我还没有看到任何更新的参考资料。

答案2

因为它常用的文件系统都不支持它们

据我所知(抱歉,有一堆链接、内存和谷歌,没有什么凝聚力足以在此列出作为参考),这从来不是因为下划线系统不支持创建时间属性,而是因为它们甚至都不能同意这是一个有用的功能。

http://www.pathname.com/fhs/pub/fhs-2.3.html

POSIX 列出了三个时间戳。它们都不是创建时间。

如果我没记错的话,争论是这样的:

> Give me a use case where we can't already do that using what we already have.
< Some examples were submitted
> All of these are convoluted beyond usefulness. 
> Ok, Ok, *maybe* a couple of these don't suck. 
> Now how do you see handling file systems that don't track this?
< several ideas that were not the same. 
< Basically everyone had a special case that would work, but not 
< one that always works. Fight about fallbacks and other special handling. 
> Ok, lets table that for now. What should we call this field
< At least 6 different answers emerged.
> So, you want to break POSIX standards, 
> you can't really come up with a good reason why, 
> you can't come up with a good fall back, and 
> you can't even come up with a name. 
> Sounds like it's specific to the file system to me, and that 
> should be "extended data" accessible by tools and not as 
> a core stat in the Kernel.

现在很多都是记忆和阅读一些旧的邮件列表。我也没有真正处于争论的中心。由于嵌入式 Linux 系统的胖驱动程序的一些临时工作,我被列入了邮件列表。我之所以提到这一点,是因为肯定有比我对我只关心的事情的记忆更权威的来源。

我确实记得最重要的是这样一个事实:没有人能提出一个好的用例,没有人能就如何处理其他 40 个不支持创建时间的常用文件系统的字段达成一致,甚至为该领域命名也引发了一场激烈的争论。

答案3

诞生时间是在几个 Linux 本机文件系统中,而不仅仅是 ext4。

从 Linux 内核 4.11 版本开始(2017 年 4 月),有一个新的statx()系统调用来检索它。然而,相应的包装函数尚未添加到 GNU libc 中(截至 2018-06-26)。2019年编辑现在已在 2.28 中添加),并且 GNU statls、等工具find尚未更新以使用它(2019-08-22 编辑GNU stat/Linux 系统上的 glibc 2.28 或更高版本从 coreutils 8.31 开始支持它;2021-01-04 编辑GNU自 coreutils 8.32 起ls就有了--time=birth

你可以用类似的东西来做到这perl一点:

perl -MPOSIX -e '
  require "syscall.ph";
  $buf = "\0" x 0x100; # enough space for a struct statx
  for (@ARGV) {
    # hardcode: AT_FDCWD == -100
    #           AT_SYMLINK_NOFOLLOW = 0x100 (lstat()-like)
    #           STATX_BTIME = 0x800 for the mask
    #           80: offset of the btime in the struct
    syscall(&SYS_statx, -100, $_, 0x100, 0x800, $buf) == 0
      or die "$_: $!\n";
    ($t, $n) = unpack("x80QQ", $buf);
    $n = sprintf("%09d", $n);
    print strftime("%F %T.$n %z\n", localtime $t)
  }' -- "$file"

如果你syscall.ph没有SYS_statx,你也可以对其进行硬编码。在 amd64 架构上是 332。或者尝试:

printf '#include <syscall.h>\n__NR_statx\n' | gcc -E -xc - | tail -n 1

现在,出生时间已经很少有用了。这不是文件中数据的年龄(数据被写入文件它们已被创建),也不一定是该文件在目录中以该名称出现的时间(它可能已创建为不同的名称并重命名或链接到那里,并且其内容或属性在其间多次更改)。


1 作为一种特殊情况,对于 ext4,如果创建的文件系统的 inode 大小为 128 字节,则不包括出生时间字段。

相关内容