@@ -397,6 +397,18 @@ void blk_insert_flush(struct request *rq)
unsigned int policy = blk_flush_policy(fflags, rq);
struct blk_flush_queue *fq = blk_get_flush_queue(q, rq->mq_ctx);
+ /*
+ * REQ_FUA does not apply to read requests because:
+ * - There is no way to reliably force media access for read operations
+ * with a block device that does not support FUA.
+ * - Not all block devices support FUA for read operations (e.g. ATA
+ * devices with NCQ support turned off).
+ */
+ if (!op_is_write(rq->cmd_flags) && (rq->cmd_flags & REQ_FUA)) {
+ blk_mq_end_request(rq, BLK_STS_NOTSUPP);
+ return;
+ }
+
/*
* @policy now records what operations need to be done. Adjust
* REQ_PREFLUSH and FUA for the driver.
For block devices that do not support FUA, the blk-flush machinery using preflush/postflush (synchronize cache) does not enforce media access on the device side for a REQ_FUA read. Furthermore, not all block devices support FUA for read operations (e.g. ATA devices with NCQ support turned off). Finally, while all the blk-flush.c code is clearly intended at processing FUA writes, there is no explicit checks verifying that the issued request is a write. Add a check at the beginning of blk_insert_flush() to ensure that any REQ_FUA read request is failed, reporting "not supported" to the user. Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com> --- block/blk-flush.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)