]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - block/bounce.c
MAINTAINERS: update vmxnet3 driver maintainer
[linux.git] / block / bounce.c
index 1d05c422c932ad56d705f94deed6cce0891ff9d3..6a3e68292273b03d3aa12a82a4a5af4979e95d60 100644 (file)
@@ -113,45 +113,50 @@ int init_emergency_isa_pool(void)
 static void copy_to_high_bio_irq(struct bio *to, struct bio *from)
 {
        unsigned char *vfrom;
-       struct bio_vec tovec, *fromvec = from->bi_io_vec;
+       struct bio_vec tovec, fromvec;
        struct bvec_iter iter;
+       /*
+        * The bio of @from is created by bounce, so we can iterate
+        * its bvec from start to end, but the @from->bi_iter can't be
+        * trusted because it might be changed by splitting.
+        */
+       struct bvec_iter from_iter = BVEC_ITER_ALL_INIT;
 
        bio_for_each_segment(tovec, to, iter) {
-               if (tovec.bv_page != fromvec->bv_page) {
+               fromvec = bio_iter_iovec(from, from_iter);
+               if (tovec.bv_page != fromvec.bv_page) {
                        /*
                         * fromvec->bv_offset and fromvec->bv_len might have
                         * been modified by the block layer, so use the original
                         * copy, bounce_copy_vec already uses tovec->bv_len
                         */
-                       vfrom = page_address(fromvec->bv_page) +
+                       vfrom = page_address(fromvec.bv_page) +
                                tovec.bv_offset;
 
                        bounce_copy_vec(&tovec, vfrom);
                        flush_dcache_page(tovec.bv_page);
                }
-
-               fromvec++;
+               bio_advance_iter(from, &from_iter, tovec.bv_len);
        }
 }
 
 static void bounce_end_io(struct bio *bio, mempool_t *pool)
 {
        struct bio *bio_orig = bio->bi_private;
-       struct bio_vec *bvec, *org_vec;
+       struct bio_vec *bvec, orig_vec;
        int i;
-       int start = bio_orig->bi_iter.bi_idx;
+       struct bvec_iter orig_iter = bio_orig->bi_iter;
 
        /*
         * free up bounce indirect pages used
         */
        bio_for_each_segment_all(bvec, bio, i) {
-               org_vec = bio_orig->bi_io_vec + i + start;
-
-               if (bvec->bv_page == org_vec->bv_page)
-                       continue;
-
-               dec_zone_page_state(bvec->bv_page, NR_BOUNCE);
-               mempool_free(bvec->bv_page, pool);
+               orig_vec = bio_iter_iovec(bio_orig, orig_iter);
+               if (bvec->bv_page != orig_vec.bv_page) {
+                       dec_zone_page_state(bvec->bv_page, NR_BOUNCE);
+                       mempool_free(bvec->bv_page, pool);
+               }
+               bio_advance_iter(bio_orig, &orig_iter, orig_vec.bv_len);
        }
 
        bio_orig->bi_status = bio->bi_status;