在close(2)之后调用fsync(2) [英] Calling fsync(2) after close(2)

查看:421
本文介绍了在close(2)之后调用fsync(2)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

场景:

任务代码(省略错误检查):

Task code (error checking omitted):

// open, write and close
fd = open(name);
write(fd, buf, len);
close(fd);
< more code here **not** issuing read/writes to name but maybe open()ing it >
// open again and fsync
fd = open(name);
fsync(fd);

在系统中不再有其他任务同时访问name.

No more tasks accessing name concurrently in the system.

是否已定义,更重要的是,它是否会同步name引用的inode上可能存在的未完成写入?即,我会在fsync之后从文件中读回buf吗?

Is it defined, and more important, will it sync possible outstanding writes on the inode referred by name? ie, will I read back buf from the file after the fsync?

从POSIX http://pubs.opengroup.org/onlinepubs/009695399 /functions/fsync.html 我会说这似乎合法...

From POSIX http://pubs.opengroup.org/onlinepubs/009695399/functions/fsync.html I would say it seems legit ...

谢谢.

编辑5月18日: 感谢您的回答和研究.我在2016年向一个extfs首席开发人员(Ted)提出了这个问题,并得到了以下答案:"Posix不能保证,但实际上,它应该适用于大多数 文件系统,包括ext4. Posix规范中的关键措辞是:

Edit may 18: Thanks for the answers and research. I took this question (in 2016) to one of the extfs lead developers (Ted) and got this answer: "It's not guaranteed by Posix, but in practice it should work on most file systems, including ext4. The key wording in the Posix specification is:

fsync()函数应请求打开文件的所有数据 ^^^^^^^^^^^^^^^^^^ fildes命名的描述符将被传输到存储设备 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 与fildes描述的文件关联.

The fsync() function shall request that all data for the open file ^^^^^^^^^^^^^^^^^ descriptor named by fildes is to be transferred to the storage device ^^^^^^^^^^^^^^^^^^^^^^^^^^ associated with the file described by fildes.

它不会说"fildes描述的文件的所有数据...." 说打开的文件描述符的所有数据".所以从技术上讲数据 不能保证由另一个文件描述符写入的文件同步 磁盘.

It does not say "all data for the file described by fildes...." it says "all data for the open file descriptor". So technically data written by another file descriptor is not guaranteed to be synced to disk.

在实践中,文件系统不会尝试通过fd引入脏数据 继续,所以您不必担心.而OS所写的内容远不止于此 严格要求是符合标准的,这就是您要做的 即使没有保证,也可以找到."这比完全相同的双重保证"要明确,但即使是过时的,也很权威.

In practice, file systems don't try dirty data by which fd it came in on, so you don't need to worry. And an OS which writes more than what is strictly required is standards compliant, and so that's what you will find in general, even if it isn't guaranteed." This is less specific than "exact same durabily guarrantees" but is quite authoritative, even though maybe outdated.

我想做的是在单个文件上运行的同步"命令. 像fsync/some/file一样,无需同步整个文件系统,例如可以在shell脚本中使用它. 现在(从几年前开始)gnu coreutils'sync'可在单个文件上运行,并且完全可以做到这一点(open/fsync).提交: https://github.com/coreutils/coreutils/commit/8b2bf5295f353016d4f5e6 /p>

What I was trying to do was a 'sync' command that worked on single files. Like fsync /some/file without having to sync the whole filesystem, to use it in shell scripts for example. Now (since a few years ago) gnu coreutils 'sync' works on single files and does exactly this (open/fsync). commit: https://github.com/coreutils/coreutils/commit/8b2bf5295f353016d4f5e6a2317d55b6a8e7fd00

推荐答案

close() + re- open() + fsync()不能提供与fsync() +相同的保证close().

No, close()+re-open()+fsync() does not provide the same guarantees as fsync()+close().

来源:我提出了这个问题 linux-fsdevel邮件列表和得到答案:

Source: I took this question to the linux-fsdevel mailing list and got the answer:

close()/re-open()/fsync()序列是否提供相同的持久性 保证为fsync()/close()?

Does a sequence of close()/re-open()/fsync() provide the same durability guarantees as fsync()/close()?

简短的回答是否",后者提供了更好的保证. 更长的答案是持久性保证取决于内核版本, 因为情况在v4.13,v4.14中有所变化,现在又在 v4.17-rc和稳定的内核.

The short answer is no, the latter provides a better guaranty. The longer answer is that durability guarantees depends on kernel version, because situation has been changing in v4.13, v4.14 and now again in v4.17-rc and stable kernels.

其他相关链接是:

  • https://wiki.postgresql.org/wiki/Fsync_Errors ("fsyncgate")
  • Mailing list entry PostgreSQL's handling of fsync() errors is unsafe and risks data loss at least on XFS
  • Writing programs to cope with I/O errors causing lost writes on Linux from the same author

尤其是后面的链接描述了如何

In particular, the latter links describe how

  • after closing an FD, you lose all ways to enforce durability
  • after an fsync() fails, you cannot call fsync() again in the hope that now your data would be written
  • you must re-do/confirm all writing work if that happens

这篇关于在close(2)之后调用fsync(2)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆