我有一个必须始终存在于文件系统上的硬链接。硬链接点的inode不是恒定的。我想更新硬链接而不添加临时条目到目录。
(创建没有目录条目的文件可以使用open(2)
和temp标志来完成。)
我面临的问题是更换/更新硬链接。从相关系统调用的文档来看,似乎我只有两个选项,并且都没有避免临时文件:
使用renameat
,可以确保硬链接始终存在。但是,它必须使用硬链接,因此需要临时文件(更不用说它无法取消引用符号链接)。
使用linkat
,可以在不牺牲其他文件的情况下生成硬链接。但它不能覆盖现有文件;要求删除原始硬链接。
是否可以创建指向替换旧名称相同名称的inode的链接?
答案 0 :(得分:3)
您需要有另一个文件可以切换链接。然而
rename
,renameat
不需要将inode链接到同一目录中;它们只需要inode存在于同一个文件系统中,或者更具体地说是在同一个挂载点上;否则Linux rename
会失败并显示EXDEV
:
EXDEV
oldpath
和newpath
不在同一个挂载的文件系统上。 (Linux允许在多个点安装文件系统,但rename()不能在不同的位置上运行 挂载点,即使两者都安装了相同的文件系统。)
从Linux 3.11开始,有一种方法可以创建一个 new 文件,而无需将其链接到文件系统:open(2) has a new flag O_TMPFILE
:
O_TMPFILE
(自Linux 3.11起)创建一个未命名的临时文件。 pathname参数 指定目录;将创建一个未命名的inode 该目录的文件系统。写的任何东西 当最后一个文件描述符时,结果文件将丢失 关闭,除非文件被赋予名称。
必须使用O_TMPFILE
或O_RDWR
之一指定
O_WRONLY
并且,可选地,O_EXCL
。如果未指定O_EXCL
,则linkat
(2)可用于将临时文件链接到 文件系统,使其成为永久性的,使用类似的代码 以下内容:char path[PATH_MAX]; fd = open("/path/to/dir", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); /* File I/O on 'fd'... */ snprintf(path, PATH_MAX, "/proc/self/fd/%d", fd); linkat(AT_FDCWD, path, AT_FDCWD, "/path/for/file", AT_SYMLINK_FOLLOW);
在这种情况下,
open()
模式参数确定文件 权限模式,与O_CREAT
一样。
手册告诉O_TMPFILE
的两个常见用例之一是
创建一个最初不可见的文件,然后是 填充数据并调整为适当的 文件系统属性(chown(2),chmod(2),fsetxattr(2), 在原子地链接到文件系统之前 处于完全形成状态(使用如所述的linkat(2) 上文)。
除此之外还有很多不足之处:文件系统还必须支持O_TMPFILE
; ext [234]支持它,3.15中的XFS也支持它; 3.16中的btrfs;此外,它可能仍然不适合您的情况,因为linkat
需要AT_SYMLINK_FOLLOW
renameat
不可用;如果目标名称已经存在,`linkat 不替换目标。