summaryrefslogtreecommitdiffstats
path: root/block/blk-barrier.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/blk-barrier.c')
-rw-r--r--block/blk-barrier.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/block/blk-barrier.c b/block/blk-barrier.c
index 0d710c9d403..f0faefca032 100644
--- a/block/blk-barrier.c
+++ b/block/blk-barrier.c
@@ -13,7 +13,6 @@
* blk_queue_ordered - does this queue support ordered writes
* @q: the request queue
* @ordered: one of QUEUE_ORDERED_*
- * @prepare_flush_fn: rq setup helper for cache flush ordered writes
*
* Description:
* For journalled file systems, doing ordered writes on a commit
@@ -22,15 +21,8 @@
* feature should call this function and indicate so.
*
**/
-int blk_queue_ordered(struct request_queue *q, unsigned ordered,
- prepare_flush_fn *prepare_flush_fn)
+int blk_queue_ordered(struct request_queue *q, unsigned ordered)
{
- if (!prepare_flush_fn && (ordered & (QUEUE_ORDERED_DO_PREFLUSH |
- QUEUE_ORDERED_DO_POSTFLUSH))) {
- printk(KERN_ERR "%s: prepare_flush_fn required\n", __func__);
- return -EINVAL;
- }
-
if (ordered != QUEUE_ORDERED_NONE &&
ordered != QUEUE_ORDERED_DRAIN &&
ordered != QUEUE_ORDERED_DRAIN_FLUSH &&
@@ -44,7 +36,6 @@ int blk_queue_ordered(struct request_queue *q, unsigned ordered,
q->ordered = ordered;
q->next_ordered = ordered;
- q->prepare_flush_fn = prepare_flush_fn;
return 0;
}
@@ -79,7 +70,7 @@ unsigned blk_ordered_req_seq(struct request *rq)
*
* http://thread.gmane.org/gmane.linux.kernel/537473
*/
- if (!blk_fs_request(rq))
+ if (rq->cmd_type != REQ_TYPE_FS)
return QUEUE_ORDSEQ_DRAIN;
if ((rq->cmd_flags & REQ_ORDERED_COLOR) ==
@@ -143,10 +134,10 @@ static void queue_flush(struct request_queue *q, unsigned which)
}
blk_rq_init(q, rq);
- rq->cmd_flags = REQ_HARDBARRIER;
- rq->rq_disk = q->bar_rq.rq_disk;
+ rq->cmd_type = REQ_TYPE_FS;
+ rq->cmd_flags = REQ_HARDBARRIER | REQ_FLUSH;
+ rq->rq_disk = q->orig_bar_rq->rq_disk;
rq->end_io = end_io;
- q->prepare_flush_fn(q, rq);
elv_insert(q, rq, ELEVATOR_INSERT_FRONT);
}
@@ -203,7 +194,7 @@ static inline bool start_ordered(struct request_queue *q, struct request **rqp)
/* initialize proxy request and queue it */
blk_rq_init(q, rq);
if (bio_data_dir(q->orig_bar_rq->bio) == WRITE)
- rq->cmd_flags |= REQ_RW;
+ rq->cmd_flags |= REQ_WRITE;
if (q->ordered & QUEUE_ORDERED_DO_FUA)
rq->cmd_flags |= REQ_FUA;
init_request_from_bio(rq, q->orig_bar_rq->bio);
@@ -236,7 +227,8 @@ static inline bool start_ordered(struct request_queue *q, struct request **rqp)
bool blk_do_ordered(struct request_queue *q, struct request **rqp)
{
struct request *rq = *rqp;
- const int is_barrier = blk_fs_request(rq) && blk_barrier_rq(rq);
+ const int is_barrier = rq->cmd_type == REQ_TYPE_FS &&
+ (rq->cmd_flags & REQ_HARDBARRIER);
if (!q->ordseq) {
if (!is_barrier)
@@ -261,7 +253,7 @@ bool blk_do_ordered(struct request_queue *q, struct request **rqp)
*/
/* Special requests are not subject to ordering rules. */
- if (!blk_fs_request(rq) &&
+ if (rq->cmd_type != REQ_TYPE_FS &&
rq != &q->pre_flush_rq && rq != &q->post_flush_rq)
return true;
@@ -319,6 +311,15 @@ int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask,
if (!q)
return -ENXIO;
+ /*
+ * 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
+ * here will panic. Ensure there is a request function before issuing
+ * the barrier.
+ */
+ if (!q->make_request_fn)
+ return -ENXIO;
+
bio = bio_alloc(gfp_mask, 0);
bio->bi_end_io = bio_end_empty_barrier;
bio->bi_bdev = bdev;