10

fsync 和 syncfs 有什么区别?

int syncfs(int fd);
int fsync(int fd);

fync 的联机帮助页说明如下:

fsync() 将文件描述符 fd 引用的文件的所有修改的内核数据(即修改的缓冲区缓存页面)传输(“刷新”)到磁盘设备(或其他永久存储设备),以便所有即使在系统崩溃或重新启动后,也可以检索更改的信息。这包括写入或刷新磁盘缓存(如果存在)。呼叫阻塞,直到设备报告传输已完成。它还刷新与文件关联的元数据信息(请参阅 stat(2))。

syncfs 的联机帮助页说明如下:

sync() 导致对文件元数据和数据的所有缓冲修改都写入底层文件系统。

syncfs() 与 sync() 类似,但仅同步包含由打开文件描述符 fd 引用的文件的文件系统。

对我来说,两者似乎都是平等的。他们正在同步文件描述符和相关元数据引用的文件。

4

2 回答 2

17

首先,fsync()(and sync()) 是 POSIX 标准函数,而syncfs()仅适用于 Linux。

所以可用性是一大区别。

来自POSIX 标准fsync()

fsync()函数应请求将由 命名的打开文件描述符的所有数据fildes传输到与由 描述的文件关联的存储设备fildes。传输的性质是实现定义的。在系统完成该操作或检测到错误之前,该fsync()函数不应返回。

请注意,这只是一个请求。

来自POSIX 标准sync()

sync()功能应使内存中更新文件系统的所有信息都被安排写出到所有文件系统。

写作虽然已安排好,但不一定在从sync().

同样,这不是保证会发生的事情。

syncfs()(和sync())状态的 Linux 手册页

sync()导致对文件系统元数据和缓存文件数据的所有未决修改写入底层文件系统。

syncfs()类似sync(),但只同步包含由打开文件描述符引用的文件的文件系统fd

请注意,函数返回的时间是未指定的。

状态的Linux手册页fsync()

fsync()将文件描述符引用的文件的所有修改的内核数据(即修改的缓冲区缓存页面)传输(“刷新”)fd到磁盘设备(或其他永久存储设备),以便即使可以检索所有更改的信息如果系统崩溃或重新启动。这包括写入或刷新磁盘缓存(如果存在)。呼叫阻塞,直到设备报告传输已完成。

除了刷新文件数据,fsync()还刷新与文件关联的元数据信息(参见 inode(7))。

调用fsync()不一定确保包含该文件的目录中的条目也已到达磁盘。为此,fsync()还需要明确的目录文件描述符。

请注意,Linux 提供的保证fsync()sync()orsyncfs()和 POSIX 为fsync()and提供的保证要强得多sync()

总之:

  1. POSIX fsync():“请将此文件的数据写入磁盘”
  2. POSIX sync():“当你处理它时将所有数据写入磁盘”
  3. Linux sync():“将所有数据写入磁盘(什么时候开始?)”
  4. Linux syncfs():“将与该文件关联的文件系统的所有数据写入磁盘(当你找到它时?)”
  5. Linux fsync():“将此文件的所有数据和元数据写入磁盘,直到你这样做才返回”

sync()请注意,Linux 手册页没有指定何时syncfs()返回。

于 2018-01-09T16:05:18.097 回答
3

我认为目前的答案并不完整。对于 Linux:

根据标准规范(例如,POSIX.1-2001),sync() 安排写入,但可能在实际写入完成之前返回。然而,Linux 等待 I/O 完成,因此sync()或 提供与分别在系统或文件系统中的每个文件上调用syncfs()的相同的保证。fsync

在 1.3.20 版本之前,Linux 不会等待 I/O 完成才返回。

这在“注释”和“错误”部分的sync(2)页面上有所提及。

于 2020-04-02T06:40:18.873 回答