Can inode and crtime be used as a unique file identifier?
我在Linux上有一个文件索引数据库。目前,我使用文件路径作为标识符。但是,如果文件被移动/重命名,则其路径会更改,并且无法将数据库记录与新文件匹配,因此必须删除/重新创建记录。更糟糕的是,如果目录被移动/重命名,那么我必须删除/重新创建所有文件和嵌套目录的记录。
我想使用索引节点号作为唯一的文件标识符,但是索引节点号可以是因此,我想知道是否可以使用一对{inode,crtime}作为唯一文件标识符。我希望在ext4上使用i_crtime在NTFS上使用creation_time。在同一文件系统中重命名或移动文件或目录时,inode和crtime的有限测试(使用ext4)的确确实保持不变。
因此,问题是是否存在文件的inode或crtime的情况。可能会更改。例如,fsck或碎片整理或分区大小是否可以更改inode或crtime或文件?
对http://msdn.microsoft.com/zh-cn/library/aa363788(VS.85 ).aspx表示:
- "在NTFS文件系统中,文件会保持相同的文件ID,直到被删除为止。"但是在某些情况下还会:
- " ,一个文件的ID "
那么,它们提到的那些情况是什么?
请注意,我研究了类似的问题:
- 如何确定linux中文件的唯一性?
- 执行'mv A B':'inode'会改变吗?
- 在Linux中检测移动或重命名文件的最佳方法?
,但他们没有回答我的问题。
- {device_nr,inode_nr}是系统上文件(\\\\" inode \\\\")的唯一ID。这些保证是稳定的(也许是NFS的例外)。移动文件不会更改索引节点,它只是将链接的索引节点移动到另一个目录。跨文件系统移动是不同的。顺便说一句:微软文档中提到NTFS是该规则的可能例外(就像我的NFS例外,可能还有NAS / SAN存储?)
- 顺便说一句:什么是crtime? UFS仅具有{ctime,atime,mtime}
- crtime是文件创建时间。它是在ext4中添加的。其他帖子对此进行了详细讨论。
Unix中i节点的分配和管理取决于文件系统。因此,对于每个文件系统,答案可能会有所不同。
对于Ext3文件系统(最受欢迎),i节点被重用,因此不能用作唯一的文件标识符,也不会根据
在Ext3中,在位向量中跟踪i节点,每个位代表一个i节点编号。释放i节点后,该位设置为零。当需要一个新的i节点时,将在位向量中搜索第一个零位,然后重用i节点号(可能先前已分配给另一个文件)。
天真的结论是编号最少的可用i节点将被重用。但是,Ext3文件系统非常复杂且经过高度优化,因此,即使可以清楚地重用i-node编号,也不应做任何假设。
来自ialloc.c的源代码,其中分配了i节点的位置:
There are two policies for allocating an inode. If the new inode is a
directory, then a forward search is made for a block group with both
free space and a low directory-to-inode ratio; if that fails, then of
he groups with above-average free space, that group with the fewest
directories already is chosen. For other inodes, search forward from
the parent directory's block group to find a free inode.
为Ext3管理此操作的源代码称为ialloc,最终版本位于此处:https://github.com/torvalds/linux/blob/master /fs/ext3/ialloc.c
- 当然,索引节点可以重用,我在开始时就提到了这一点。我的问题是,是否可以将一对{inode,crtime}用作唯一标识符,尤其是对于现有文件,这些值是否可以更改。
- 答案取决于您是否要冒险更改文件系统算法。当前,在删除文件之前,索引节点号不会更改。此外,使用truncate(2)截断文件时,内核不会更改索引节点号。但是,许多程序在修改文件时都会重新创建文件,从而更改索引节点号。如果您已经编写了所有涉及的软件,并且明确地知道将不会删除索引节点本身,那么至少在ext3文件系统上,您可以冒险。考虑到许多因素,我会保持谨慎。
- 您是否知道与动态索引节点有关的文件系统如何与重用索引节点有关?即使在动态分配新的inode时,ZFS和BTRFS也会重用inode。这些技术都是基于位向量的吗?如果有一百万个文件怎么办,那么此inode位向量将具有一百万个位?
- {device_nr,inode_nr}是系统中inode的唯一标识符
- 将文件移动到其他目录不会更改其inode_nr
- linux inotify界面使您可以监视对索引节点(文件或目录)的更改。
附加说明:
- 在文件系统中移动文件的处理方式不同。 (实际上是删除副本)
- 联网的文件系统(或已安装的NTFS)不能总是保证inodenumbers
- 的稳定性Microsoft不是unix供应商,其文档也不涵盖Unix或其版本。文件系统,并且应该被忽略(NTFS \\的内部除外)
附加文本:旧的Unix adagium \\\\"一切都是文件\\\\"实际上应该是:\\\\ "一切都是索引节点"。索引节点携带除名称之外的有关文件(或目录或特殊文件)的所有元信息。文件名实际上只是一个碰巧链接到特定inode的目录条目。移动文件意味着:创建到相同inode的新链接,结束删除链接到该inode的旧目录条目.inode元数据可以通过stat()和fstat()以及lstat()系统调用获得。 >
- wildplasser写道:" {device_nr,inode_nr}是系统上文件(" inode ")的唯一ID。这些保证是稳定的" ............. ……由whome"保证"?您是否参考某些文档?因为快速搜索"保证稳定"的inode会带来"无法保证节点号稳定" ........ ,但inode不足,因为它们可以被重用。因此,我决定也使用crtime。我需要了解它的稳定性。
- 如果索引节点号被重用,则首先必须不使用它。 (如果链接计数变为零,则inode未使用/不存在,然后可以重用,包括其编号)。请参见stat(2)有关核心信息:请参阅Bach或文件系统驱动程序的源文档。
- wildplasser写道:\\\\"如果要重用inode编号,则首先必须不使用它。\\\\" jhnlmn:当然,我写了\\\\",但是如果删除文件并创建另一个文件,则可以重用inode编号。 \\"在我的问题中
- 索引节点号是文件系统上现有文件的标识符。将其存储在数据库中,然后删除文件,就像在没有CASCADE选项的情况下在DBMS中获取外键一样。您的系统仍将通过一个现在引用另一个实体的数字来引用一个不存在的文件。解决方案很简单:不要删除文件,如果要删除文件,请删除对它的所有引用。
- wildplasser写道:微软不是Unix供应商,它的文档没有涵盖Unix或它的文件系统,应该被忽略jhnlmn:这是不正确的。可以先将磁盘插入Linux,然后再插入Windows,然后再插入Linux。或者Windows和Linux可以在双重引导系统上一个接一个地引导。因此,了解MS如何处理文件ID同样重要。现在,我对Windows下的NTFS中的文件ID的稳定性比Linux下的更有信心,这在Linux上已有所记载。
- wildplasser写道:解决方案很简单:不要删除文件,如果要删除文件,请删除对它的所有引用。 ................. jhnlmn:那该怎么做?如何区分是删除文件还是移动文件?从一开始这就是我的问题。对不起,如果我不清楚。 (PS:并且,请不要告诉我使用iNotify,因为它不可扩展)。
- 注意选择性引用(NTFS的内部除外)BTW:您仍然可以阅读源代码。它是开放的,你知道。
- <blockquote> > NOTE the selective quoting (except for NTFS's internals) </blockquote>我试图遵循stackoverflow.com上的edit-help#comment-formatting,但没有任何效果。 <blockquote> BTW: You can still read the source. It's open, you know. </blockquote>是的,我知道。我正在阅读源代码一段时间,但是由于始终有机会错过100万行中的一行,因此我无法获得确切的答案。同样,如果阅读源文件是一个答案,那么像stackoverflow.com这样的网站将不存在。
- @jhnlmn:请澄清您的陈述。他们似乎受到FUD,恕我直言的困扰。
我猜dB应用程序需要考虑从备份还原文件的情况,这将保留文件crtime,但不会保留inode编号。