我有一个硬链接,该链接必须始终存在于文件系统上。硬链接点的索引节点不是恒定的。我想更新硬链接而不向目录添加临时条目。
(可以使用open(2)
temp标志来创建没有目录条目的文件。)
我面临的问题是更换/更新硬链接。从有关系统调用的文档中,似乎我只有两个选择,而且都没有避免使用临时文件:
使用renameat
,可以确保硬链接始终存在。但是,它必须消耗一个硬链接,因此需要一个临时文件(更不用说它不能取消引用符号链接)。
使用linkat
,可以在不牺牲其他文件的情况下产生硬链接。但是它不能覆盖现有文件;需要删除原始硬链接。
是否可以创建到一个索引节点的链接,该链接用相同的名称替换一个较旧的链接?
您需要另一个文件以将链接切换到该文件。但是rename
,renameat
不需要将inode链接在同一目录中;它们只需要将inode存在于同一文件系统上,或更具体地说,存在于同一安装点上;否则,Linux将rename
失败并显示EXDEV
:
EXDEV
oldpath
并且newpath
不在相同的已挂载文件系统上。(Linux允许在多个点上挂载文件系统,但是即使两个文件上都挂载了相同的文件系统,rename()也无法跨不同的挂载点工作。)
从Linux 3.11开始,有一种方法可以在不将其链接到文件系统的情况下创建新文件:open(2)具有一个新标志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()
mode参数与一样确定文件许可模式O_CREAT
。
该手册指出,2种常见用例之一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并没有更换目标。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句