写入磁盘映像后是否需要运行"同步"?



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

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

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

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

有没有人证明它是有用或无用的?

TL;DR:dd后运行blockdev --flushbufs /dev/device

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

  • ioctl(block_dev, BLKFLSBUF, 0)打电话给blkdev_flushbuf().考虑到它的名字,它应该刷新与设备关联的缓存(或者我认为您可以认为设备驱动程序中存在错误)。我认为它还应该负责刷新硬件缓存(如果存在)。注意e2fsprogs使用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将在/dev/device上调用fsync()。但是,我认为这是无用的,因为dd没有接触任何文件系统。

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

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

编辑

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

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

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

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

最新更新