Common way to write an image to disk looks like:
dd if=file.img of=/dev/device
After this command, is it necessary to run sync
?
sync(2) explains it only flushes filesystem caches. Since dd
command is not related to any filesystem, I think it is not necessary to run sync
. However, block layer is complex and in doubt, most people prefers to run sync
.
Does anyone has a proof that it is useful or useless?
Advertisement
Answer
TL;DR: Run blockdev --flushbufs /dev/device
after dd
.
I tried to follow the different paths in kernel. Here is what I understood:
ioctl(block_dev, BLKFLSBUF, 0)
callblkdev_flushbuf()
. Considering its name, it should flush caches associated with device (or I think you can consider there is bug in device driver). I think it should also responsible to flush hardware caches if they exist. Noticee2fsprogs
useBLKFLSBUF
.fdatasync()
(andfsync()
) will callblkdev_fsync()
. It looks likeblkdev_flushbuf()
but it only impact range of data written by current process (It usefilemap_write_and_wait_range()
whileBLKFLSBUF
usefilemap_write_and_wait
).- Closing a block device calls
blkdev_close()
that do not flush buffers. sync()
will callsync_fs()
. It will flush filesystem caches and callfsync()
on underlying block device.- Command
sync /dev/device
will callfsync()
on/dev/device
. However, I think it is useless sincedd
didn’t touch to any filesystem.
So my conclusions is that call to sync
has no (direct) impact on block device. However, passing fdatasync
(or fsync
) to dd
is the only way to guarantee that data are correctly written on media.
If have you run dd
but you missed to pass fdatasync
, running sync /dev/device
is not sufficient. You have have to run dd
with fdatasync
on whole device. Alternatively, you can call BLKFLSBUF
to flush whole device. Unfortunately, there is no standard command for that.
EDIT
You can issue a BLKFLSBUF
with blockdev --flushbufs /dev/device
.