So instead of cracking my head on the relaxed barriers I've decided to
do the easiet part first. That is relaxing explicit cache flushes
done by blkdev_issue_flush. These days these are handled as an
empty barrier, which is completely overkill. Instead take advantage
of the way we now handle flushes, that is as REQ_FLUSH FS requests.
Do a few updates to the block layer so that we handle REQ_FLUSH
correctly and we can make blkdev_issue_flush submit them directly.
All request based block drivers should just work with it, but bio
based remappers will need some additional work. The next patch
will do this for DM, but I haven't quite grasped the barrier code
in MD yet. Despite doing a lot REQ_HARDBARRIER tests DRBD doesn't
actually advertize any ordered mode so it's not affected. The
barrier handling in the loop driver is currently broken anyway,
and I'm still undecided if I want to fix it before or after
this conversion.
- /*
- * For an empty barrier, there's no actual BAR request, which
- * in turn makes POSTFLUSH unnecessary. Mask them off.
- */
- if (!blk_rq_sectors(rq)) {
- q->ordered &= ~(QUEUE_ORDERED_DO_BAR |
- QUEUE_ORDERED_DO_POSTFLUSH);
- /*
- * Empty barrier on a write-through device w/ ordered
- * tag has no command to issue and without any command
- * to issue, ordering by tag can't be used. Drain
- * instead.
- */
- if ((q->ordered & QUEUE_ORDERED_BY_TAG) &&
- !(q->ordered & QUEUE_ORDERED_DO_PREFLUSH)) {
- q->ordered &= ~QUEUE_ORDERED_BY_TAG;
- q->ordered |= QUEUE_ORDERED_BY_DRAIN;
- }
- }
+ BUG_ON(!blk_rq_sectors(rq));
/* stash away the original request */
blk_dequeue_request(rq);
@@ -311,6 +293,9 @@ int blkdev_issue_flush(struct block_devi
if (!q)
return -ENXIO;
+ if (!(q->next_ordered & QUEUE_ORDERED_DO_PREFLUSH))
+ return 0;
+
/*
* some block devices may not have their queue correctly set up here
* (e.g. loop device without a backing file) and so issuing a flush
@@ -327,7 +312,7 @@ int blkdev_issue_flush(struct block_devi
bio->bi_private = &wait;