场景:

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

// 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

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

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

谢谢。

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

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

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

实际上,文件系统不会尝试从中获取脏数据
继续,所以您不必担心。而一个OS所写的不只是什么
严格要求是符合标准的,所以这就是您
即使没有保证,也总会找到。”这比“完全相同的双重保证”要明确,但即使过时也很有权威。

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

最佳答案

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

来源:我took this questionlinux-fsdevel邮件列表和got the answer:



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

其他相关链接是:

  • https://wiki.postgresql.org/wiki/Fsync_Errors(“fsyncgate”)
  • 邮件列表条目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

  • 特别是后面的链接描述了

    FD关闭后
  • ,您将失去所有增强耐用性的方法
  • fsync()失败后的
  • ,您无法再次调用fsync(),希望现在将您的数据写入
  • 如果发生这种情况,您会must re-do/confirm all writing work
  • 关于c - 在close(2)之后调用fsync(2),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37288453/

    10-13 02:59