diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/ll_rw_blk.c | 56 |
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 | ||
305 | EXPORT_SYMBOL(blk_queue_ordered); | 305 | EXPORT_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 | **/ | ||
317 | void blk_queue_issue_flush_fn(struct request_queue *q, issue_flush_fn *iff) | ||
318 | { | ||
319 | q->issue_flush_fn = iff; | ||
320 | } | ||
321 | |||
322 | EXPORT_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 | ||
2667 | EXPORT_SYMBOL(blk_execute_rq); | 2650 | EXPORT_SYMBOL(blk_execute_rq); |
2668 | 2651 | ||
2652 | static 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 | */ |
2679 | int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector) | 2670 | int 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 | ||
2695 | EXPORT_SYMBOL(blkdev_issue_flush); | 2711 | EXPORT_SYMBOL(blkdev_issue_flush); |