不使用临时文件可以覆盖硬链接吗?
Can hardlinks be overwritten without using a temporary file?
我很难link必须始终存在于文件系统上。 hardlink 分什么inode 不是常量。我想在不向目录添加临时条目的情况下更新 hardlink。
(创建没有目录条目的文件可以使用 open(2)
和临时标志来完成。)
我面临的问题是 replacing/updating 困难link。从相关系统调用的文档来看,我似乎只有两个选择,而且都没有避免使用临时文件:
使用renameat
,可以确保hardlink始终存在。但是,它必须消耗硬 link,因此需要一个临时文件(更不用说它无法取消引用符号 links)。
使用linkat
,可以在不牺牲另一个文件的情况下生成硬link。但它不能覆盖现有文件;要求删除原来的hard link.
是否有可能创建一个 link 到 inode 以替换具有相同名称的旧 link?
您需要将 link 切换到另一个文件。然而
rename
、renameat
不需要inode在同一目录下link;他们只需要 inode 存在于同一个文件系统上,或者 更具体地说,存在于同一个挂载点 上;否则 Linux rename
失败 EXDEV
:
EXDEV
oldpath
and newpath
are not on the same mounted filesystem. (Linux permits a filesystem to be mounted at multiple points, but rename() does not work across different
mount points, even if the same filesystem is mounted on both.)
自 Linux 3.11 以来,有一种方法可以创建 new 文件,而无需 link 将其写入文件系统:open(2) has a new flag O_TMPFILE
:
O_TMPFILE
(since Linux 3.11)
Create an unnamed temporary file. The pathname argument
specifies a directory; an unnamed inode will be created in
that directory's filesystem. Anything written to the
resulting file will be lost when the last file descriptor is
closed, unless the file is given a name.
O_TMPFILE
must be specified with one of O_RDWR
or O_WRONLY
and, optionally, O_EXCL
. If O_EXCL
is not specified, then
linkat
(2) can be used to link the temporary file into the
filesystem, making it permanent, using code like the
following:
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);
In this case, the open()
mode argument determines the file
permission mode, as with O_CREAT
.
手册告诉我们 O_TMPFILE
的两个常见用例之一是
Creating a file that is initially invisible, which is then
populated with data and adjusted to have appropriate
filesystem attributes (chown(2), chmod(2), fsetxattr(2),
etc.) before being atomically linked into the filesystem
in a fully formed state (using linkat(2) as described
above).
这有很多缺点,除了它很新:文件系统还必须支持 O_TMPFILE
; ext[234] 支持它,3.15 中的 XFS 也支持; 3.16 中的 btrfs;此外,它可能仍然不适合您的情况,因为 linkat
需要 AT_SYMLINK_FOLLOW
而 renameat
不可用;如果目标名称已经存在,`linkat not 替换目标。
我很难link必须始终存在于文件系统上。 hardlink 分什么inode 不是常量。我想在不向目录添加临时条目的情况下更新 hardlink。
(创建没有目录条目的文件可以使用 open(2)
和临时标志来完成。)
我面临的问题是 replacing/updating 困难link。从相关系统调用的文档来看,我似乎只有两个选择,而且都没有避免使用临时文件:
使用
renameat
,可以确保hardlink始终存在。但是,它必须消耗硬 link,因此需要一个临时文件(更不用说它无法取消引用符号 links)。使用
linkat
,可以在不牺牲另一个文件的情况下生成硬link。但它不能覆盖现有文件;要求删除原来的hard link.
是否有可能创建一个 link 到 inode 以替换具有相同名称的旧 link?
您需要将 link 切换到另一个文件。然而
rename
、renameat
不需要inode在同一目录下link;他们只需要 inode 存在于同一个文件系统上,或者 更具体地说,存在于同一个挂载点 上;否则 Linux rename
失败 EXDEV
:
EXDEV
oldpath
andnewpath
are not on the same mounted filesystem. (Linux permits a filesystem to be mounted at multiple points, but rename() does not work across different mount points, even if the same filesystem is mounted on both.)
自 Linux 3.11 以来,有一种方法可以创建 new 文件,而无需 link 将其写入文件系统:open(2) has a new flag O_TMPFILE
:
O_TMPFILE
(since Linux 3.11)Create an unnamed temporary file. The pathname argument specifies a directory; an unnamed inode will be created in that directory's filesystem. Anything written to the resulting file will be lost when the last file descriptor is closed, unless the file is given a name.
O_TMPFILE
must be specified with one ofO_RDWR
orO_WRONLY
and, optionally,O_EXCL
. IfO_EXCL
is not specified, thenlinkat
(2) can be used to link the temporary file into the filesystem, making it permanent, using code like the following: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);
In this case, the
open()
mode argument determines the file permission mode, as withO_CREAT
.
手册告诉我们 O_TMPFILE
的两个常见用例之一是
Creating a file that is initially invisible, which is then populated with data and adjusted to have appropriate filesystem attributes (chown(2), chmod(2), fsetxattr(2), etc.) before being atomically linked into the filesystem in a fully formed state (using linkat(2) as described above).
这有很多缺点,除了它很新:文件系统还必须支持 O_TMPFILE
; ext[234] 支持它,3.15 中的 XFS 也支持; 3.16 中的 btrfs;此外,它可能仍然不适合您的情况,因为 linkat
需要 AT_SYMLINK_FOLLOW
而 renameat
不可用;如果目标名称已经存在,`linkat not 替换目标。