block: set REQ_SYNC if we clear REQ_FUA|REQ_PREFLUSH
authorJens Axboe <axboe@fb.com>
Wed, 9 Nov 2016 02:39:28 +0000 (19:39 -0700)
committerJens Axboe <axboe@fb.com>
Wed, 9 Nov 2016 02:39:28 +0000 (19:39 -0700)
If we insert a flush request, we clear REQ_PREFLUSH and/or REQ_FUA,
depending on flush settings. Since op_is_sync() factors those flags
in for deciding whether this request is sync or not, we should
set REQ_SYNC to avoid screwing up this accounting.

This should be less fragile.

Reported-by: Logan Gunthorpe <logang@deltatee.com>
Fixes: b685d3d65ac ("block: treat REQ_FUA and REQ_PREFLUSH as synchronous")
Signed-off-by: Jens Axboe <axboe@fb.com>
block/blk-flush.c

index c486b7aa62eeb7eb51f617d8a589774a382278b6..1bdbb3d3e5f579b296f2831f14de7c2787e0f5de 100644 (file)
@@ -395,6 +395,13 @@ void blk_insert_flush(struct request *rq)
        if (!(fflags & (1UL << QUEUE_FLAG_FUA)))
                rq->cmd_flags &= ~REQ_FUA;
 
+       /*
+        * REQ_PREFLUSH|REQ_FUA implies REQ_SYNC, so if we clear any
+        * of those flags, we have to set REQ_SYNC to avoid skewing
+        * the request accounting.
+        */
+       rq->cmd_flags |= REQ_SYNC;
+
        /*
         * An empty flush handed down from a stacking driver may
         * translate into nothing if the underlying device does not