8

我正在开发一个基于 Perl 的文件同步工具。它将文件下载到一个临时目录(保证与真实文件在同一个文件系统上),然后将临时文件移动到旧文件上,保留权限、所有权和 ACL 等元数据。我想知道如何在 Linux 上实现最后一步。

在 Mac OS X 上,至少在 C 中,我会使用这个exchangedata函数。这需要两个文件名作为参数并交换它们的内容,使所有元数据(除了 mtime)保持不变。它保证了操作是原子的——所有的读者都可以看到旧文件或新文件,而不会介于两者之间。不幸的是,我认为它在 Linux 上不可用。

我知道它是rename原子移动的,但它不保留元数据。另一方面,我可以打开文件并用新文件的内容覆盖数据,这将保留所有元数据,但不是原子操作。关于解决这个问题的任何建议?

4

2 回答 2

6

我在这里看到的唯一方法是从您要替换的文件中读取元数据,将其应用于临时文件,然后将临时文件重命名为旧文件。(rename显然,保留了源文件属性。)

于 2009-11-07T18:14:48.373 回答
4

特定于文件系统,但是...

ioctl 交换XFSXFS_IOC_SWAPEXT上两个文件描述符的范围。

#include <xfs/xfs.h>
#include <xfs/xfs_dfrag.h>

xfs_swapext_t sx = {
    ...,
    .sx_fdtarget = fd1,
    .sx_fdtmp    = fd2,
    ...
};
xfs_swapext(fd1, &sx);

有关示例用法,请参见xfs_fsr的源代码。

于 2009-11-07T20:47:16.693 回答