aboutsummaryrefslogtreecommitdiffstats
path: root/block/ll_rw_blk.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/ll_rw_blk.c')
-rw-r--r--block/ll_rw_blk.c56
1 files changed, 36 insertions, 20 deletions
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 4fde3a3c92d3..4df7d027eb06 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -304,23 +304,6 @@ int blk_queue_ordered(struct request_queue *q, unsigned ordered,
304 304
305EXPORT_SYMBOL(blk_queue_ordered); 305EXPORT_SYMBOL(blk_queue_ordered);
306 306
307/**
308 * blk_queue_issue_flush_fn - set function for issuing a flush
309 * @q: the request queue
310 * @iff: the function to be called issuing the flush
311 *
312 * Description:
313 * If a driver supports issuing a flush command, the support is notified
314 * to the block layer by defining it through this call.
315 *
316 **/
317void blk_queue_issue_flush_fn(struct request_queue *q, issue_flush_fn *iff)
318{
319 q->issue_flush_fn = iff;
320}
321
322EXPORT_SYMBOL(blk_queue_issue_flush_fn);
323
324/* 307/*
325 * Cache flushing for ordered writes handling 308 * Cache flushing for ordered writes handling
326 */ 309 */
@@ -2666,6 +2649,14 @@ int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk,
2666 2649
2667EXPORT_SYMBOL(blk_execute_rq); 2650EXPORT_SYMBOL(blk_execute_rq);
2668 2651
2652static void bio_end_empty_barrier(struct bio *bio, int err)
2653{
2654 if (err)
2655 clear_bit(BIO_UPTODATE, &bio->bi_flags);
2656
2657 complete(bio->bi_private);
2658}
2659
2669/** 2660/**
2670 * blkdev_issue_flush - queue a flush 2661 * blkdev_issue_flush - queue a flush
2671 * @bdev: blockdev to issue flush for 2662 * @bdev: blockdev to issue flush for
@@ -2678,7 +2669,10 @@ EXPORT_SYMBOL(blk_execute_rq);
2678 */ 2669 */
2679int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector) 2670int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
2680{ 2671{
2672 DECLARE_COMPLETION_ONSTACK(wait);
2681 struct request_queue *q; 2673 struct request_queue *q;
2674 struct bio *bio;
2675 int ret;
2682 2676
2683 if (bdev->bd_disk == NULL) 2677 if (bdev->bd_disk == NULL)
2684 return -ENXIO; 2678 return -ENXIO;
@@ -2686,10 +2680,32 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
2686 q = bdev_get_queue(bdev); 2680 q = bdev_get_queue(bdev);
2687 if (!q) 2681 if (!q)
2688 return -ENXIO; 2682 return -ENXIO;
2689 if (!q->issue_flush_fn)
2690 return -EOPNOTSUPP;
2691 2683
2692 return q->issue_flush_fn(q, bdev->bd_disk, error_sector); 2684 bio = bio_alloc(GFP_KERNEL, 0);
2685 if (!bio)
2686 return -ENOMEM;
2687
2688 bio->bi_end_io = bio_end_empty_barrier;
2689 bio->bi_private = &wait;
2690 bio->bi_bdev = bdev;
2691 submit_bio(1 << BIO_RW_BARRIER, bio);
2692
2693 wait_for_completion(&wait);
2694
2695 /*
2696 * The driver must store the error location in ->bi_sector, if
2697 * it supports it. For non-stacked drivers, this should be copied
2698 * from rq->sector.
2699 */
2700 if (error_sector)
2701 *error_sector = bio->bi_sector;
2702
2703 ret = 0;
2704 if (!bio_flagged(bio, BIO_UPTODATE))
2705 ret = -EIO;
2706
2707 bio_put(bio);
2708 return ret;
2693} 2709}
2694 2710
2695EXPORT_SYMBOL(blkdev_issue_flush); 2711EXPORT_SYMBOL(blkdev_issue_flush);