Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
3.9 kB · 95 lines
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596==========================================Explicit volatile write back cache control==========================================
Introduction------------
Many storage devices, especially in the consumer market, come with volatilewrite back caches. That means the devices signal I/O completion to theoperating system before data actually has hit the non-volatile storage. Thisbehavior obviously speeds up various workloads, but it means the operatingsystem needs to force data out to the non-volatile storage when it performsa data integrity operation like fsync, sync or an unmount.
The Linux block layer provides two simple mechanisms that let filesystemscontrol the caching behavior of the storage device. These mechanisms area forced cache flush, and the Force Unit Access (FUA) flag for requests.
Explicit cache flushes----------------------
The REQ_PREFLUSH flag can be OR ed into the r/w flags of a bio submitted fromthe filesystem and will make sure the volatile cache of the storage devicehas been flushed before the actual I/O operation is started. This explicitlyguarantees that previously completed write requests are on non-volatilestorage before the flagged bio starts. In addition the REQ_PREFLUSH flag can beset on an otherwise empty bio structure, which causes only an explicit cacheflush without any dependent I/O. It is recommend to usethe blkdev_issue_flush() helper for a pure cache flush.
Forced Unit Access------------------
The REQ_FUA flag can be OR ed into the r/w flags of a bio submitted from thefilesystem and will make sure that I/O completion for this request is onlysignaled after the data has been committed to non-volatile storage.
Implementation details for filesystems--------------------------------------
Filesystems can simply set the REQ_PREFLUSH and REQ_FUA bits and do not have toworry if the underlying devices need any explicit cache flushing and howthe Forced Unit Access is implemented. The REQ_PREFLUSH and REQ_FUA flagsmay both be set on a single bio.
Feature settings for block drivers----------------------------------
For devices that do not support volatile write caches there is no driversupport required, the block layer completes empty REQ_PREFLUSH requests beforeentering the driver and strips off the REQ_PREFLUSH and REQ_FUA bits fromrequests that have a payload.
For devices with volatile write caches the driver needs to tell the block layerthat it supports flushing caches by setting the
BLK_FEAT_WRITE_CACHE
flag in the queue_limits feature field. For devices that also support the FUAbit the block layer needs to be told to pass on the REQ_FUA bit by also settingthe
BLK_FEAT_FUA
flag in the features field of the queue_limits structure.
Implementation details for bio based block drivers--------------------------------------------------
For bio based drivers the REQ_PREFLUSH and REQ_FUA bit are simply passed on tothe driver if the driver sets the BLK_FEAT_WRITE_CACHE flag and the driverneeds to handle them.
*NOTE*: The REQ_FUA bit also gets passed on when the BLK_FEAT_FUA flags is_not_ set. Any bio based driver that sets BLK_FEAT_WRITE_CACHE also needs tohandle REQ_FUA.
For remapping drivers the REQ_FUA bits need to be propagated to underlyingdevices, and a global flush needs to be implemented for bios with theREQ_PREFLUSH bit set.
Implementation details for blk-mq drivers-----------------------------------------
When the BLK_FEAT_WRITE_CACHE flag is set, REQ_OP_WRITE | REQ_PREFLUSH requestswith a payload are automatically turned into a sequence of a REQ_OP_FLUSHrequest followed by the actual write by the block layer.
When the BLK_FEAT_FUA flags is set, the REQ_FUA bit is simply passed on for theREQ_OP_WRITE request, else a REQ_OP_FLUSH request is sent by the block layerafter the completion of the write request for bio submissions with the REQ_FUAbit set.