6

Is there a difference in practice between running blockdev --flushbufs and sync(1) on Linux? (apart from blockdev flushing for a specific device, and sync being system-wide).

sync(1) manpage says it flushes file system buffers (only?). If do I/O to a drive (with say, dd) without going through a file-system layer, is sync really ineffectual?

When should I use one instead of the other?

Totor
  • 20,040

2 Answers2

2

If do I/O to a drive (with say, dd) without going through a file-system layer, is sync really inefficient?

This begs the question that writing to a device node bypasses "the file-system layer". I suppose in a sense it obviously does...

In any case, it doesn't matter. If what you are doing does not involve caching, then running sync (or some equivalent) anyway wouldn't be "inefficient": if there's nothing to sync, it's a trivial call.

When should one use one instead of the other?

I guess when you want to target a particular partition, blockdev makes sense. I can't see how it would have any particular advantage over sync otherwise (and vice versa).

goldilocks
  • 87,661
  • 30
  • 204
  • 262
  • I strongly suspect that Totor meant ineffectual (i.e. having no effect), not inefficient. – Gilles 'SO- stop being evil' Nov 02 '13 at 23:52
  • What if blockdev flushes block device buffer that sync doesn't touch? and conversely? – Totor Feb 21 '14 at 23:04
  • I didn't understand this I guess when you want to target a particular partition.. by this do you mean dd as well as mounting single block device partition both or using single block partition using dd only ? we are mounting one partition(ext4) and removing rfs content and updating new rfs into it. Do we need to use sync only or combination of sync and blockdev --flushbufs both ? – ART Dec 09 '15 at 09:42
1

blockdev --flushbufs, if implemented by the underlying driver/hardware, will flush write buffers on the device itself. In entreprise hardware block devices usually do not keep dirty write buffers unless backed up by a battery, where it could still be desired to flush them before moving the hardware or replacing the battery (this is usually done automatically at the end of the shutdown process, just before performing an ACPI shutdown or reset).

Most entreprise and higher-end desktop mechanical drives have a read/write cache that can be configured to do write caching or not, and this is the cache that would be flushed with this ioctl. It could be useful to ensure all data is flushed before unplugging an USB or eSATA-attached block device, even after sync has been performed.

This ioctl is not always reliable, some drivers or devices could be lacking an implementation or intercepting calls. IIRC even older versions of LVM used to intercept this ioctl when used on logical volumes and fail to flush the physical devices.

sync()/syncfs()/fsync()/fdatasync() have a different purpose, they will sync all unwritten data/metadata back to the device. That data may include dirty mmap()'ed pages, dirty buffers in the VFS layer and uncommitted filesystem changes. fdadasync() flushes only the data for a specific file so it's the most efficient way of making sure data changes have been flushed (it may still delay some metadata updates unless required, such as file size changes). All other sync() calls will flush everything on a file, filesystem or all filesystems. It should be the program's job to sync their data if it's deemed important, and if you have to resort to a full sync call to ensure everything is properly written it's obviously much less efficient (the sync program can also sync a specific filesystems or file's data, see man sync).

If the goal is removing a device and you can unmount it, you don't even have to sync; unmounting the filesystem will already flush all buffers at the OS level (blockdev --flushbufs may still be required if there is a large write cache and you're disconnecting the device immediately after). If the system is in a bad state and you can't unmount, then sync may be the next best thing you can do before rebooting (try to kill all applications that may write to it first).

Also although write caches on the block devices are prone to cause data loss, most modern journaling filesystems cope very well with it, avoiding even the need to run an fsck after a power failure (the filesystem's journal will have everything needed to correct the metadata to a known good state). OTOH the same is usually not true for the file data on the filesystem and you may end up with corrupted files if not flushed properly by badly designed applications.

  • And if do I/O to a drive (with say, dd) without going through a file-system layer, is sync ineffectual? – Totor Oct 12 '21 at 11:36
  • @Totor This is a very good point; according to this answer your device may indeed have active caches, but only if it's open by another application - the cache will be flushed on the last close(), so in general you should be safe. – Thomas Guyot-Sionnest Oct 20 '21 at 18:34
  • BTW one thing I didn't cover is application-level caches. GLibc's stdlib has its own level of caching, and many interpreted languages also have their own caching on top of it. Also files access aren't consistent between normal reads and mmap as those cache are distinct (and mmap writes too needs to be flushed before they can be sync'ed). This means syncing a file/fs while it's being used by an application doesn't guarantee the application's data is safely written if that application isn't flushing/syncing its data itself. – Thomas Guyot-Sionnest Oct 20 '21 at 18:39