inode和crtime可用作唯一文件标识符吗?

15

我在Linux上有一个文件索引数据库。目前我使用文件路径作为标识符。 但是,如果文件被移动/重命名,则它的路径会更改,我无法将我的DB记录与新文件匹配,并且必须删除/重新创建记录。更糟糕的是,如果目录被移动/重命名,那么我必须删除/重新创建所有文件和嵌套目录的记录。

我想使用inode号作为唯一的文件标识符,但是inode号可以在文件被删除并创建另一个文件时被重用。

因此,我想知道是否可以使用一对{inode,crtime}作为唯一的文件标识符。 我希望在ext4上使用i_crtime,在NTFS上使用creation_time。 在我的有限测试(使用ext4)中,当在同一文件系统中重命名或移动文件或目录时,inode和crtime确实保持不变。

所以问题是,是否存在inode或crtime可能更改的情况。 例如,fsck或碎片整理或分区调整是否会更改文件的inode或crtime?

有趣的是,http://msdn.microsoft.com/en-us/library/aa363788%28VS.85%29.aspx说:

  • "在NTFS文件系统中,文件保持相同的文件ID,直到它被删除。"
    但也:
  • "在某些情况下,文件的文件ID可能会随时间而改变。"

那么,他们提到的是哪些情况?

请注意,我研究了类似的问题:

但它们没有回答我的问题。


{device_nr,inode_nr}是系统上文件(“inode”)的唯一标识符。这些标识符保证稳定(可能除了NFS)。移动文件不会更改inode,它只是将链接移到另一个目录中的inode。跨文件系统移动是不同的。顺便说一下:微软文档提到NTFS可能是规则的一个例外(就像我的NFS例外和可能的NAS / SAN存储一样?) - wildplasser
顺便问一下,crtime是什么?UFS只有{ctime,atime,mtime}。 - wildplasser
crtime是文件创建时间。它在ext4中被添加。它在其他帖子中有详细讨论。 - jhnlmn
对于Linux系统,在NFS中inode是可重用的,而且你可能需要在NFS上索引文件,因此你不能只使用INODE(我们都同意这一点)。所以,对于Linux系统,我建议同时使用inode和inode generation作为唯一键。请告诉我们你采取了哪种解决方案(这个问题没有答案)。 - Pierre
3个回答

7
Unix中i-node的分配和管理取决于文件系统。因此,对于每个文件系统,答案可能会有所不同。
对于Ext3文件系统(最流行的文件系统),i-node会被重用,因此不能用作唯一的文件标识符,也不会按照任何可预测的模式进行重用。
在Ext3中,i-node被跟踪在位向量中,每个位表示一个单独的i-node号码。当i-node被释放时,它的位被设置为零。当需要新的i-node时,位向量会搜索第一个零位,并重新使用i-node号码(该号码可能已经分配给另一个文件)。
这可能导致天真的结论是,最低编号的可用i-node将被重新使用。然而,Ext3文件系统是复杂和高度优化的,因此不应做出任何关于i-node号码何时以及如何被重用的假设,尽管它们显然会被重用。
从ialloc.c的源代码中可以看到i-node的分配情况:
有两种分配inode的策略。如果新的inode是一个目录,则会向前搜索一个块组,找到既有空闲空间又有低目录到inode比率的块组;如果失败,则选择具有平均以上空闲空间且已有目录最少的块组。对于其他的inode,在父目录的块组中向前搜索以找到一个空闲的inode。
管理这个过程的Ext3源代码称为ialloc,其权威版本在这里:https://github.com/torvalds/linux/blob/master/fs/ext3/ialloc.c

当然,inode可以被重用,我在最开始提到了这一点。我的问题是是否可以将{inode,crtime}作为唯一标识符使用,特别是这些值是否会更改现有文件的信息。 - jhnlmn
2
答案取决于您是否愿意冒文件系统算法更改的风险。目前,直到文件被删除,i-node编号才会发生变化。此外,内核在使用truncate(2)截断文件时不会更改i-node编号。然而,许多程序在修改文件时重新创建文件,从而更改i-node编号。如果您编写了所有涉及的软件,并且明确知道i-node本身不会被删除,则可以冒这个风险,至少在ext3文件系统上。考虑到众多因素,我会保持谨慎。 - Gary Wisniewski
你知道动态索引节点文件系统在重复使用索引节点方面的工作原理吗?即使是在动态分配新索引节点时,ZFS和BTRFS也会重复使用索引节点。此外,所有这些技术都基于位向量吗?如果有一百万个文件,那么这个索引节点位向量将有一百万个位,对吗? - CMCDragonkai

6
  • {device_nr,inode_nr}是系统内一个 inode 的唯一标识符
  • 将文件移动到另一个目录中不会改变其inode_nr
  • Linux的inotify接口使您能够监视对inode(文件或目录)的更改

额外说明:

  • 跨文件系统移动文件会以不同方式处理。(实际上是复制和删除)
  • 网络文件系统(或挂载的NTFS)不能始终保证inodenumbers的稳定性
  • Microsoft不是Unix供应商,其文档不涵盖Unix或其文件系统,应忽略(除了NTFS的内部信息)

额外文本:旧的Unix格言“万物皆文件”实际上应该是“万物皆inode”。inode携带有关文件(或目录或特殊文件)的所有元信息,除了名称。实际上,文件名只是一个链接到特定inode的目录条目。移动文件意味着:创建指向相同inode的新链接,并删除链接到它的旧目录条目。 可以通过stat()fstat()lstat() 系统调用获取inode元数据。


3
wildplasser写道:“{device_nr,inode_nr}是系统上文件(“inode”)的唯一标识符。这些保证是稳定的。” ................... 由谁保证?您是否有参考某些文档的链接? 因为快速搜索“guaranteed to be stable” inode会得到“Inode numbers are -not- guaranteed to be stable” .................... 此外,仅使用inode是不够的,因为它们可以被重用。 所以,我决定同时使用crtime。 我需要了解它的稳定性如何。 - jhnlmn
2
wildplasser写道:“如果inode号码被重复使用,它必须首先未被使用。” jhnlmn:当然,我在我的问题中写道:“但是如果文件被删除并创建另一个文件,则可以重复使用inode号码。” - jhnlmn
wildplasser写道:解决方案很简单:不要删除文件,如果你确实要删除文件:删除所有对它的引用。jhnlmn: 那怎么做呢?如何区分文件被删除还是被移动了?这就是我一开始的问题。如果我没有表达清楚,那我很抱歉。(附注:请不要告诉我使用iNotify,因为它不可扩展)。 - jhnlmn
1
请注意,除了NTFS的内部结构外,引用是有选择性的。我试图按照http://stackoverflow.com上的编辑帮助#注释格式进行操作,但没有任何作用。顺便说一句:你仍然可以阅读源代码。它是公开的,你知道的。是的,我知道。我已经阅读了一段时间的源代码,但我无法得到一个确定的答案,因为总有可能会错过100万行中的一行。此外,如果阅读源代码就是答案,那么像stackoverflow.com这样的网站就不存在了。 - jhnlmn
@jhnlmn:请澄清你的陈述。在我看来,它们似乎受到了FUD的困扰。 - wildplasser
显示剩余4条评论

-1

我猜dB应用程序需要考虑这样一种情况,即文件可能会从备份中恢复,这将保留文件的创建时间(crtime),但不保留inode号。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接