场景:
任务代码(省略错误检查):
// 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描述的文件相关的数据……”,而是说“所有打开的文件描述符的数据”。因此,从另一个文件描述符写入的数据在技术上不能保证同步到磁盘。实际上,文件系统不会尝试通过哪个fd来脏数据,所以您不需要担心。如果操作系统写入比严格要求更多的内容,则符合标准,因此即使没有保证,通常也会发现这种情况。这比“完全相同的持久性保证”不太具体,但非常权威,尽管可能已过时。
我想要做的是一个针对单个文件的“同步”命令,例如在shell脚本中使用时,可以像fsync /some/file一样工作,而不必同步整个文件系统。 现在(几年前开始),gnu coreutils的“sync”可以在单个文件上工作,并且确实可以执行此操作(打开/fsync)。提交记录:https://github.com/coreutils/coreutils/commit/8b2bf5295f353016d4f5e6a2317d55b6a8e7fd00
filedes
所引用的inode上的挂起请求是“打开文件描述符的数据”。 - jneighblinux-fsdevel
上提出了这个问题。我得到确认,至少在写作时,close()/re-open()/fsync()
不能像fsync()/close()
一样提供相同的保证。 - nh2