C 是否可以在不使用临时文件的情况下覆盖硬链接?

C 是否可以在不使用临时文件的情况下覆盖硬链接?,c,linux,system-calls,inode,C,Linux,System Calls,Inode,我有一个硬链接,它必须始终存在于文件系统上。硬链接点的inode不是常数。我想在不向目录中添加临时条目的情况下更新硬链接 (可以使用带有temp标志的open(2)创建没有目录项的文件。) 我面临的问题是更换/更新硬链接。从有关系统调用的文档中,我似乎只有两个选项,而且两个选项都不能避免使用临时文件: 使用重命名,可以确保硬链接始终存在。但是,它必须使用硬链接,因此需要临时文件(更不用说它无法取消对符号链接的引用) 使用linkat,可以在不牺牲其他文件的情况下生成硬链接。但它不能覆盖现有文件;

我有一个硬链接,它必须始终存在于文件系统上。硬链接点的inode不是常数。我想在不向目录中添加临时条目的情况下更新硬链接

(可以使用带有temp标志的
open(2)
创建没有目录项的文件。)

我面临的问题是更换/更新硬链接。从有关系统调用的文档中,我似乎只有两个选项,而且两个选项都不能避免使用临时文件:

  • 使用
    重命名
    ,可以确保硬链接始终存在。但是,它必须使用硬链接,因此需要临时文件(更不用说它无法取消对符号链接的引用)

  • 使用
    linkat
    ,可以在不牺牲其他文件的情况下生成硬链接。但它不能覆盖现有文件;需要删除原始硬链接


  • 是否可以创建指向inode的链接以替换具有相同名称的旧链接

    您需要另一个文件来切换链接。然而
    重命名
    重命名不需要将inode链接到同一目录中;它们只需要inode存在于同一个文件系统上,或者更具体地说,存在于同一个挂载点上;否则,Linux
    rename
    将因
    EXDEV
    而失败:

    EXDEV

    oldpath
    newpath
    不在同一个挂载的文件系统上。(Linux允许在多个点安装文件系统,但rename()不能跨不同的点工作 挂载点,即使两个上都挂载了相同的文件系统。)


    由于Linux 3.11,有一种方法可以创建新文件,而无需将其链接到文件系统:

    O_TMPFILE
    (从Linux 3.11开始)

    创建一个未命名的临时文件。路径名参数 指定一个目录;将在中创建一个未命名的inode 那个目录是文件系统。有没有写给警察的信 当最后一个文件描述符被删除时,生成的文件将丢失 关闭,除非指定了文件名

    O_TMPFILE
    必须使用
    O_RDWR
    O_WRONLY
    并且,可选地,
    O_exc
    。如果未指定
    O_exc
    ,则
    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_create

    本手册说明
    O_TMPFILE
    的两个常见用例之一是

    创建一个最初不可见的文件,然后 用数据填充并调整为具有适当的 文件系统属性(chown(2)、chmod(2)、fsetxattr(2), 等),然后以原子方式链接到文件系统 处于完全成形状态(使用如上所述的linkat(2)) 上文)


    除此之外,它还有许多缺点:文件系统还必须支持
    O_TMPFILE
    ;ext[234]确实支持它,3.15中的XFS也支持它;3.16中的btrfs;此外,它可能仍然与您的情况不匹配,因为
    linkat
    需要
    AT\u SYMLINK\u FOLLOW
    ,这对于
    renameat
    不可用;如果目标名称已经存在,`linkat不会替换目标。

    您想更改什么,只是更改链接的名称,还是更改链接到的(inode->)文件的实际内容?我希望文件(目录项)指向不同的inode。遗憾的是,必须创建临时文件。似乎有非官方的兴趣在_REPLACE
    中添加
    ,这将解决这个问题[1],但除此之外,临时文件是唯一的方法。[1]: