为什么使用 mv 命令重命名文件会改变 inode 的“更改”日期和时间?

为什么使用 mv 命令重命名文件会改变 inode 的“更改”日期和时间?

文件 hello.c 被重命名为 hi.c。正如 stat 命令的输出所示,[change] 时间戳已更改。通常当文件的索引节点被修改时它也会改变。为什么用mv命令重命名会改变inode的内容以及实际上修改的是哪个属性?

xyz@linuxPC:~/Documents$ stat hello.c
 File: ‘hello.c’
 Size: 568          Blocks: 8          IO Block: 4096   regular file
Device: 809h/2057d  Inode: 261889      Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/ xyz)   Gid: ( 1000/ xyz)
Access: 2015-04-22 19:54:34.889330399 +0530
Modify: 2015-04-22 19:54:34.241330427 +0530
Change: 2015-06-21 15:46:45.365465523 +0530
Birth: -
xyz@linuxPC:~/Documents$ mv hello.c hi.c
xyz@linuxPC:~/Documents$ stat hi.c 
 File: ‘hi.c’
 Size: 568          Blocks: 8          IO Block: 4096   regular file
Device: 809h/2057d  Inode: 261889      Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/ xyz)   Gid: ( 1000/ xyz)
Access: 2015-04-22 19:54:34.889330399 +0530
Modify: 2015-04-22 19:54:34.241330427 +0530
Change: 2015-06-21 15:48:23.361469822 +0530
Birth: -

答案1

我自己很感兴趣并做了一些挖掘。起初我认为这是某种副作用,例如节点获得了 2 个链接,然后原始链接被删除,而 ctime 更像是意外而不是故意的操作。

如果有人不清楚,该文件由一个 inode 表示,其中包含没有什么与名字有关。由于硬链接计数器,索引节点“知道”它获得了多少个名称,但对于这些名称是什么或它们驻留在哪个目录中,它的线索为零。

有了这个,我们来看看 POSIX (http://pubs.opengroup.org/onlinepubs/009695399/functions/rename.html):

有些实现标记为更新重命名文件的 st_ctime 字段,有些则不标记。使用 st_ctime 字段的应用程序对于重命名的文件可能会有不同的行为,除非它们被设计为允许这两种行为。

和示例实现(http://lxr.free-electrons.com/source/fs/xfs/xfs_inode.c#L2985):

/*
 * We always want to hit the ctime on the source inode.
 *
 * This isn't strictly required by the standards since the source
 * inode isn't really being changed, but old unix file systems did
 * it and some incremental backup programs won't work without it.
 */
xfs_trans_ichgtime(tp, src_ip, XFS_ICHGTIME_CHG);

就这样。

答案2

很久很久以前,命令

动量旧路径 新路径

在内部实现mv.c

关联(旧路径,新路径);
取消链接(新路径);

现在我们有一个系统调用

改名(旧路径,新路径);

但显然它在内核内部仍然以同样的方式工作。这是我的猜测,但它基于以下事实:故障模式之一重命名(2)

EMLINK

    旧路径已拥有最大数量的链接,或者...

并根据您报告的实验数据(并且我在自己的系统上确认)。

所以...

什么时候旧路径被链接到新路径,inode 的链接计数增加 1。什么时候旧路径取消链接后,inode 的链接计数会减少 1。因此,索引节点会发生更改(即使它立即更改回之前的状态)。


PS 有趣的是,POSIX 文档将 EMLINK 列为可能的错误返回代码,但是不是对于文件到文件重命名的情况。

答案3

文件的 inode 中没有任何内容发生变化,因此理想情况下 ctime 在重命名时不应更改,但这是一种方便的方法来突出显示该文件以向备份程序告知该文件的某些内容已更改。因此,对于备份程序,检查“ctime比上次备份时间更新”就足以查明全部自上次备份以来已发生任何更改的文件。

相关内容