These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / block / bounce.c
index 39d123e..2f1ec8a 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/pagemap.h>
 #include <linux/mempool.h>
 #include <linux/blkdev.h>
+#include <linux/backing-dev.h>
 #include <linux/init.h>
 #include <linux/hash.h>
 #include <linux/highmem.h>
@@ -122,20 +123,19 @@ static void copy_to_high_bio_irq(struct bio *to, struct bio *from)
        }
 }
 
-static void bounce_end_io(struct bio *bio, mempool_t *pool, int err)
+static void bounce_end_io(struct bio *bio, mempool_t *pool)
 {
        struct bio *bio_orig = bio->bi_private;
        struct bio_vec *bvec, *org_vec;
        int i;
-
-       if (test_bit(BIO_EOPNOTSUPP, &bio->bi_flags))
-               set_bit(BIO_EOPNOTSUPP, &bio_orig->bi_flags);
+       int start = bio_orig->bi_iter.bi_idx;
 
        /*
         * free up bounce indirect pages used
         */
        bio_for_each_segment_all(bvec, bio, i) {
-               org_vec = bio_orig->bi_io_vec + i;
+               org_vec = bio_orig->bi_io_vec + i + start;
+
                if (bvec->bv_page == org_vec->bv_page)
                        continue;
 
@@ -143,61 +143,44 @@ static void bounce_end_io(struct bio *bio, mempool_t *pool, int err)
                mempool_free(bvec->bv_page, pool);
        }
 
-       bio_endio(bio_orig, err);
+       bio_orig->bi_error = bio->bi_error;
+       bio_endio(bio_orig);
        bio_put(bio);
 }
 
-static void bounce_end_io_write(struct bio *bio, int err)
+static void bounce_end_io_write(struct bio *bio)
 {
-       bounce_end_io(bio, page_pool, err);
+       bounce_end_io(bio, page_pool);
 }
 
-static void bounce_end_io_write_isa(struct bio *bio, int err)
+static void bounce_end_io_write_isa(struct bio *bio)
 {
 
-       bounce_end_io(bio, isa_page_pool, err);
+       bounce_end_io(bio, isa_page_pool);
 }
 
-static void __bounce_end_io_read(struct bio *bio, mempool_t *pool, int err)
+static void __bounce_end_io_read(struct bio *bio, mempool_t *pool)
 {
        struct bio *bio_orig = bio->bi_private;
 
-       if (test_bit(BIO_UPTODATE, &bio->bi_flags))
+       if (!bio->bi_error)
                copy_to_high_bio_irq(bio_orig, bio);
 
-       bounce_end_io(bio, pool, err);
+       bounce_end_io(bio, pool);
 }
 
-static void bounce_end_io_read(struct bio *bio, int err)
+static void bounce_end_io_read(struct bio *bio)
 {
-       __bounce_end_io_read(bio, page_pool, err);
+       __bounce_end_io_read(bio, page_pool);
 }
 
-static void bounce_end_io_read_isa(struct bio *bio, int err)
+static void bounce_end_io_read_isa(struct bio *bio)
 {
-       __bounce_end_io_read(bio, isa_page_pool, err);
+       __bounce_end_io_read(bio, isa_page_pool);
 }
 
-#ifdef CONFIG_NEED_BOUNCE_POOL
-static int must_snapshot_stable_pages(struct request_queue *q, struct bio *bio)
-{
-       if (bio_data_dir(bio) != WRITE)
-               return 0;
-
-       if (!bdi_cap_stable_pages_required(&q->backing_dev_info))
-               return 0;
-
-       return test_bit(BIO_SNAP_STABLE, &bio->bi_flags);
-}
-#else
-static int must_snapshot_stable_pages(struct request_queue *q, struct bio *bio)
-{
-       return 0;
-}
-#endif /* CONFIG_NEED_BOUNCE_POOL */
-
 static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig,
-                              mempool_t *pool, int force)
+                              mempool_t *pool)
 {
        struct bio *bio;
        int rw = bio_data_dir(*bio_orig);
@@ -205,8 +188,6 @@ static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig,
        struct bvec_iter iter;
        unsigned i;
 
-       if (force)
-               goto bounce;
        bio_for_each_segment(from, *bio_orig, iter)
                if (page_to_pfn(from.bv_page) > queue_bounce_pfn(q))
                        goto bounce;
@@ -218,7 +199,7 @@ bounce:
        bio_for_each_segment_all(to, bio, i) {
                struct page *page = to->bv_page;
 
-               if (page_to_pfn(page) <= queue_bounce_pfn(q) && !force)
+               if (page_to_pfn(page) <= queue_bounce_pfn(q))
                        continue;
 
                to->bv_page = mempool_alloc(pool, q->bounce_gfp);
@@ -256,7 +237,6 @@ bounce:
 
 void blk_queue_bounce(struct request_queue *q, struct bio **bio_orig)
 {
-       int must_bounce;
        mempool_t *pool;
 
        /*
@@ -265,15 +245,13 @@ void blk_queue_bounce(struct request_queue *q, struct bio **bio_orig)
        if (!bio_has_data(*bio_orig))
                return;
 
-       must_bounce = must_snapshot_stable_pages(q, *bio_orig);
-
        /*
         * for non-isa bounce case, just check if the bounce pfn is equal
         * to or bigger than the highest pfn in the system -- in that case,
         * don't waste time iterating over bio segments
         */
        if (!(q->bounce_gfp & GFP_DMA)) {
-               if (queue_bounce_pfn(q) >= blk_max_pfn && !must_bounce)
+               if (queue_bounce_pfn(q) >= blk_max_pfn)
                        return;
                pool = page_pool;
        } else {
@@ -284,7 +262,7 @@ void blk_queue_bounce(struct request_queue *q, struct bio **bio_orig)
        /*
         * slow path
         */
-       __blk_queue_bounce(q, bio_orig, pool, must_bounce);
+       __blk_queue_bounce(q, bio_orig, pool);
 }
 
 EXPORT_SYMBOL(blk_queue_bounce);