运行 `sync` 写入磁盘映像后是否有必要?
Is running `sync` necessary after writing a disk image?
将图像写入磁盘的常用方法如下所示:
dd if=file.img of=/dev/device
这条命令后,是否需要运行sync
?
sync(2) 解释说它只刷新文件系统缓存。由于dd
命令与任何文件系统无关,我认为没有必要运行sync
。但是block layer复杂且存疑,大多数人更喜欢运行 sync
.
有没有人有证据证明它是有用的还是没用的?
TL;DR: 运行 blockdev --flushbufs /dev/device
在 dd
.
之后
我尝试遵循内核中的不同路径。这是我的理解:
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
将在 /dev/device
上调用 fsync()
。但是,我认为它没用,因为 dd
没有触及任何文件系统。
所以我的结论是调用 sync
对块设备没有(直接)影响。但是,将 fdatasync
(或 fsync
)传递给 dd
是保证数据正确写入介质的唯一方法.
如果你运行dd
但是你错过了fdatasync
,运行宁sync /dev/device
是不够的。您必须在整个设备上 运行 dd
和 fdatasync
。或者,您可以调用 BLKFLSBUF
来刷新整个设备。不幸的是,没有标准的命令。
编辑
您可以使用 blockdev --flushbufs /dev/device
发出 BLKFLSBUF
。
为确保在拔出 USB 设备之前将数据刷新到 USB 设备上,我使用以下命令:
echo 1 > /sys/block/${device}/device/delete
这样就刷出数据了,如果设备是硬盘,则磁头停放。
将图像写入磁盘的常用方法如下所示:
dd if=file.img of=/dev/device
这条命令后,是否需要运行sync
?
sync(2) 解释说它只刷新文件系统缓存。由于dd
命令与任何文件系统无关,我认为没有必要运行sync
。但是block layer复杂且存疑,大多数人更喜欢运行 sync
.
有没有人有证据证明它是有用的还是没用的?
TL;DR: 运行 blockdev --flushbufs /dev/device
在 dd
.
我尝试遵循内核中的不同路径。这是我的理解:
ioctl(block_dev, BLKFLSBUF, 0)
调用blkdev_flushbuf()
。考虑到它的名字,它应该刷新与设备相关的缓存(或者我认为你可以认为设备驱动程序中存在错误)。我认为它还应该负责刷新硬件缓存(如果存在)。注意e2fsprogs
useBLKFLSBUF
.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
是不够的。您必须在整个设备上 运行 dd
和 fdatasync
。或者,您可以调用 BLKFLSBUF
来刷新整个设备。不幸的是,没有标准的命令。
编辑
您可以使用 blockdev --flushbufs /dev/device
发出 BLKFLSBUF
。
为确保在拔出 USB 设备之前将数据刷新到 USB 设备上,我使用以下命令:
echo 1 > /sys/block/${device}/device/delete
这样就刷出数据了,如果设备是硬盘,则磁头停放。