写磁盘映像后是否需要运行`sync`?

时间:2018-03-26 10:56:05

标签: linux linux-kernel filesystems

将映像写入磁盘的常用方法如下:

dd if=file.img of=/dev/device

执行此命令后,是否需要运行sync

sync(2)解释说它只刷新文件系统缓存。由于dd命令与任何文件系统无关,我认为没有必要运行sync。但是,阻止层很复杂且有疑问,大多数人更喜欢运行sync

有没有人证明它有用或没用?

2 个答案:

答案 0 :(得分:1)

我试图遵循内核中的不同路径。以下是我的理解:

  • ioctl(block_dev, BLKFLSBUF, 0)致电blkdev_flushbuf()。考虑它的名称,它应该刷新与设备相关的缓存(或者我认为你可以认为设备驱动程序中存在错误)。我认为它还应该负责刷新硬件缓存(如果存在)。请注意e2fsprogs use BLKFLSBUF
  • fdatasync()(和fsync())将致电blkdev_fsync()。它看起来像blkdev_flushbuf()但它只影响当前流程写入的数据范围(filemap_write_and_wait_range()使用BLKFLSBUF时使用filemap_write_and_wait
  • 关闭块设备会调用不刷新缓冲区的blkdev_close()
  • sync()会致电sync_fs()。它将刷新文件系统缓存并在底层块设备上调用fsync()
  • 命令sync /dev/device将在fsync()上致电/dev/device。但是,我认为它没用,因为sync没有写入数据。

所以我的结论是对sync的调用对块设备没有(直接)影响。但是,fdatasync(或fsync)传递给dd是保证数据在媒体上正确写入的唯一方法

如果您运行dd但未通过fdatasync,则运行sync /dev/device是不够的。您必须在整个设备上使用dd运行fdatasync。或者,您可以调用BLKFLSBUF来刷新整个设备。不幸的是,没有标准命令。

修改

您可以BLKFLSBUF发出blockdev --flushbufs /dev/device

答案 1 :(得分:1)

为确保在拔出USB设备前已刷新数据,我使用以下命令:

    echo 1 > /sys/block/${device}/device/delete

这样,数据将被刷新,如果设备是硬盘驱动器,则磁头将被停放。