在 Linux 上保存原子文件而不丢失元数据

发布于 2024-08-09 21:13:10 字数 397 浏览 2 评论 0原文

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

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

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

I'm working on a Perl-based file synchronization tool. It downloads files into a temporary directory (which is guaranteed to be on the same filesystem as the real file) and then moves the temporary files into place over the old ones, preserving metadata like permissions, ownership, and ACLs. I'm wondering how to achieve that last step on Linux.

On Mac OS X, at least in C, I would use the exchangedata function. This takes two filenames as arguments and swaps their contents, leaving all metadata (besides mtime) intact. It guarantees that the operation is atomic—all readers will see either the old file or the new one, never something in between. Unfortunately, I don't think it's available on Linux.

I know that rename moves atomically, but it doesn't preserve metadata. On the other hand, I could open the file and overwrite the data with the contents of the new one, which would preserve all metadata but would not be an atomic operation. Any suggestions on tackling this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

尬尬 2024-08-16 21:13:10

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

The only approach I see here is to read the metadata from the file you are replacing, apply that to the temporary file, and then rename the temporary file over the old file. (rename preserves the source file attributes, obviously.)

情释 2024-08-16 21:13:10

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

XFS_IOC_SWAPEXT ioctl 交换 XFS。

#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 例如用法。

Filesystem-specific, but...

The XFS_IOC_SWAPEXT ioctl swaps the extents of two file descriptors on XFS.

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

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

See the sources to xfs_fsr for example usage.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文