diff options
author | Ming Lei <ming.lei@redhat.com> | 2019-02-15 06:13:19 -0500 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2019-02-15 10:40:11 -0500 |
commit | 6dc4f100c175dd0511ae8674786e7c9006cdfbfa (patch) | |
tree | b8e5204ca6eec1275187496f2d6c069643e478dc | |
parent | 2e1f4f4d2481d8bf111904c3e45fc0c4c94bf76e (diff) |
block: allow bio_for_each_segment_all() to iterate over multi-page bvec
This patch introduces one extra iterator variable to bio_for_each_segment_all(),
then we can allow bio_for_each_segment_all() to iterate over multi-page bvec.
Given it is just one mechannical & simple change on all bio_for_each_segment_all()
users, this patch does tree-wide change in one single patch, so that we can
avoid to use a temporary helper for this conversion.
Reviewed-by: Omar Sandoval <osandov@fb.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | block/bio.c | 27 | ||||
-rw-r--r-- | block/bounce.c | 6 | ||||
-rw-r--r-- | drivers/md/bcache/btree.c | 3 | ||||
-rw-r--r-- | drivers/md/dm-crypt.c | 3 | ||||
-rw-r--r-- | drivers/md/raid1.c | 3 | ||||
-rw-r--r-- | drivers/staging/erofs/data.c | 3 | ||||
-rw-r--r-- | drivers/staging/erofs/unzip_vle.c | 3 | ||||
-rw-r--r-- | fs/block_dev.c | 6 | ||||
-rw-r--r-- | fs/btrfs/compression.c | 3 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 3 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 9 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 6 | ||||
-rw-r--r-- | fs/btrfs/raid56.c | 3 | ||||
-rw-r--r-- | fs/crypto/bio.c | 3 | ||||
-rw-r--r-- | fs/direct-io.c | 4 | ||||
-rw-r--r-- | fs/exofs/ore.c | 3 | ||||
-rw-r--r-- | fs/exofs/ore_raid.c | 3 | ||||
-rw-r--r-- | fs/ext4/page-io.c | 3 | ||||
-rw-r--r-- | fs/ext4/readpage.c | 3 | ||||
-rw-r--r-- | fs/f2fs/data.c | 9 | ||||
-rw-r--r-- | fs/gfs2/lops.c | 9 | ||||
-rw-r--r-- | fs/gfs2/meta_io.c | 3 | ||||
-rw-r--r-- | fs/iomap.c | 6 | ||||
-rw-r--r-- | fs/mpage.c | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_aops.c | 5 | ||||
-rw-r--r-- | include/linux/bio.h | 11 | ||||
-rw-r--r-- | include/linux/bvec.h | 30 |
27 files changed, 127 insertions, 46 deletions
diff --git a/block/bio.c b/block/bio.c index 4db1008309ed..968b12fea564 100644 --- a/block/bio.c +++ b/block/bio.c | |||
@@ -1072,8 +1072,9 @@ static int bio_copy_from_iter(struct bio *bio, struct iov_iter *iter) | |||
1072 | { | 1072 | { |
1073 | int i; | 1073 | int i; |
1074 | struct bio_vec *bvec; | 1074 | struct bio_vec *bvec; |
1075 | struct bvec_iter_all iter_all; | ||
1075 | 1076 | ||
1076 | bio_for_each_segment_all(bvec, bio, i) { | 1077 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
1077 | ssize_t ret; | 1078 | ssize_t ret; |
1078 | 1079 | ||
1079 | ret = copy_page_from_iter(bvec->bv_page, | 1080 | ret = copy_page_from_iter(bvec->bv_page, |
@@ -1103,8 +1104,9 @@ static int bio_copy_to_iter(struct bio *bio, struct iov_iter iter) | |||
1103 | { | 1104 | { |
1104 | int i; | 1105 | int i; |
1105 | struct bio_vec *bvec; | 1106 | struct bio_vec *bvec; |
1107 | struct bvec_iter_all iter_all; | ||
1106 | 1108 | ||
1107 | bio_for_each_segment_all(bvec, bio, i) { | 1109 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
1108 | ssize_t ret; | 1110 | ssize_t ret; |
1109 | 1111 | ||
1110 | ret = copy_page_to_iter(bvec->bv_page, | 1112 | ret = copy_page_to_iter(bvec->bv_page, |
@@ -1126,8 +1128,9 @@ void bio_free_pages(struct bio *bio) | |||
1126 | { | 1128 | { |
1127 | struct bio_vec *bvec; | 1129 | struct bio_vec *bvec; |
1128 | int i; | 1130 | int i; |
1131 | struct bvec_iter_all iter_all; | ||
1129 | 1132 | ||
1130 | bio_for_each_segment_all(bvec, bio, i) | 1133 | bio_for_each_segment_all(bvec, bio, i, iter_all) |
1131 | __free_page(bvec->bv_page); | 1134 | __free_page(bvec->bv_page); |
1132 | } | 1135 | } |
1133 | EXPORT_SYMBOL(bio_free_pages); | 1136 | EXPORT_SYMBOL(bio_free_pages); |
@@ -1295,6 +1298,7 @@ struct bio *bio_map_user_iov(struct request_queue *q, | |||
1295 | struct bio *bio; | 1298 | struct bio *bio; |
1296 | int ret; | 1299 | int ret; |
1297 | struct bio_vec *bvec; | 1300 | struct bio_vec *bvec; |
1301 | struct bvec_iter_all iter_all; | ||
1298 | 1302 | ||
1299 | if (!iov_iter_count(iter)) | 1303 | if (!iov_iter_count(iter)) |
1300 | return ERR_PTR(-EINVAL); | 1304 | return ERR_PTR(-EINVAL); |
@@ -1368,7 +1372,7 @@ struct bio *bio_map_user_iov(struct request_queue *q, | |||
1368 | return bio; | 1372 | return bio; |
1369 | 1373 | ||
1370 | out_unmap: | 1374 | out_unmap: |
1371 | bio_for_each_segment_all(bvec, bio, j) { | 1375 | bio_for_each_segment_all(bvec, bio, j, iter_all) { |
1372 | put_page(bvec->bv_page); | 1376 | put_page(bvec->bv_page); |
1373 | } | 1377 | } |
1374 | bio_put(bio); | 1378 | bio_put(bio); |
@@ -1379,11 +1383,12 @@ static void __bio_unmap_user(struct bio *bio) | |||
1379 | { | 1383 | { |
1380 | struct bio_vec *bvec; | 1384 | struct bio_vec *bvec; |
1381 | int i; | 1385 | int i; |
1386 | struct bvec_iter_all iter_all; | ||
1382 | 1387 | ||
1383 | /* | 1388 | /* |
1384 | * make sure we dirty pages we wrote to | 1389 | * make sure we dirty pages we wrote to |
1385 | */ | 1390 | */ |
1386 | bio_for_each_segment_all(bvec, bio, i) { | 1391 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
1387 | if (bio_data_dir(bio) == READ) | 1392 | if (bio_data_dir(bio) == READ) |
1388 | set_page_dirty_lock(bvec->bv_page); | 1393 | set_page_dirty_lock(bvec->bv_page); |
1389 | 1394 | ||
@@ -1475,8 +1480,9 @@ static void bio_copy_kern_endio_read(struct bio *bio) | |||
1475 | char *p = bio->bi_private; | 1480 | char *p = bio->bi_private; |
1476 | struct bio_vec *bvec; | 1481 | struct bio_vec *bvec; |
1477 | int i; | 1482 | int i; |
1483 | struct bvec_iter_all iter_all; | ||
1478 | 1484 | ||
1479 | bio_for_each_segment_all(bvec, bio, i) { | 1485 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
1480 | memcpy(p, page_address(bvec->bv_page), bvec->bv_len); | 1486 | memcpy(p, page_address(bvec->bv_page), bvec->bv_len); |
1481 | p += bvec->bv_len; | 1487 | p += bvec->bv_len; |
1482 | } | 1488 | } |
@@ -1585,8 +1591,9 @@ void bio_set_pages_dirty(struct bio *bio) | |||
1585 | { | 1591 | { |
1586 | struct bio_vec *bvec; | 1592 | struct bio_vec *bvec; |
1587 | int i; | 1593 | int i; |
1594 | struct bvec_iter_all iter_all; | ||
1588 | 1595 | ||
1589 | bio_for_each_segment_all(bvec, bio, i) { | 1596 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
1590 | if (!PageCompound(bvec->bv_page)) | 1597 | if (!PageCompound(bvec->bv_page)) |
1591 | set_page_dirty_lock(bvec->bv_page); | 1598 | set_page_dirty_lock(bvec->bv_page); |
1592 | } | 1599 | } |
@@ -1596,8 +1603,9 @@ static void bio_release_pages(struct bio *bio) | |||
1596 | { | 1603 | { |
1597 | struct bio_vec *bvec; | 1604 | struct bio_vec *bvec; |
1598 | int i; | 1605 | int i; |
1606 | struct bvec_iter_all iter_all; | ||
1599 | 1607 | ||
1600 | bio_for_each_segment_all(bvec, bio, i) | 1608 | bio_for_each_segment_all(bvec, bio, i, iter_all) |
1601 | put_page(bvec->bv_page); | 1609 | put_page(bvec->bv_page); |
1602 | } | 1610 | } |
1603 | 1611 | ||
@@ -1644,8 +1652,9 @@ void bio_check_pages_dirty(struct bio *bio) | |||
1644 | struct bio_vec *bvec; | 1652 | struct bio_vec *bvec; |
1645 | unsigned long flags; | 1653 | unsigned long flags; |
1646 | int i; | 1654 | int i; |
1655 | struct bvec_iter_all iter_all; | ||
1647 | 1656 | ||
1648 | bio_for_each_segment_all(bvec, bio, i) { | 1657 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
1649 | if (!PageDirty(bvec->bv_page) && !PageCompound(bvec->bv_page)) | 1658 | if (!PageDirty(bvec->bv_page) && !PageCompound(bvec->bv_page)) |
1650 | goto defer; | 1659 | goto defer; |
1651 | } | 1660 | } |
diff --git a/block/bounce.c b/block/bounce.c index ffb9e9ecfa7e..add085e28b1d 100644 --- a/block/bounce.c +++ b/block/bounce.c | |||
@@ -165,11 +165,12 @@ static void bounce_end_io(struct bio *bio, mempool_t *pool) | |||
165 | struct bio_vec *bvec, orig_vec; | 165 | struct bio_vec *bvec, orig_vec; |
166 | int i; | 166 | int i; |
167 | struct bvec_iter orig_iter = bio_orig->bi_iter; | 167 | struct bvec_iter orig_iter = bio_orig->bi_iter; |
168 | struct bvec_iter_all iter_all; | ||
168 | 169 | ||
169 | /* | 170 | /* |
170 | * free up bounce indirect pages used | 171 | * free up bounce indirect pages used |
171 | */ | 172 | */ |
172 | bio_for_each_segment_all(bvec, bio, i) { | 173 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
173 | orig_vec = bio_iter_iovec(bio_orig, orig_iter); | 174 | orig_vec = bio_iter_iovec(bio_orig, orig_iter); |
174 | if (bvec->bv_page != orig_vec.bv_page) { | 175 | if (bvec->bv_page != orig_vec.bv_page) { |
175 | dec_zone_page_state(bvec->bv_page, NR_BOUNCE); | 176 | dec_zone_page_state(bvec->bv_page, NR_BOUNCE); |
@@ -294,6 +295,7 @@ static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig, | |||
294 | bool bounce = false; | 295 | bool bounce = false; |
295 | int sectors = 0; | 296 | int sectors = 0; |
296 | bool passthrough = bio_is_passthrough(*bio_orig); | 297 | bool passthrough = bio_is_passthrough(*bio_orig); |
298 | struct bvec_iter_all iter_all; | ||
297 | 299 | ||
298 | bio_for_each_segment(from, *bio_orig, iter) { | 300 | bio_for_each_segment(from, *bio_orig, iter) { |
299 | if (i++ < BIO_MAX_PAGES) | 301 | if (i++ < BIO_MAX_PAGES) |
@@ -313,7 +315,7 @@ static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig, | |||
313 | bio = bounce_clone_bio(*bio_orig, GFP_NOIO, passthrough ? NULL : | 315 | bio = bounce_clone_bio(*bio_orig, GFP_NOIO, passthrough ? NULL : |
314 | &bounce_bio_set); | 316 | &bounce_bio_set); |
315 | 317 | ||
316 | bio_for_each_segment_all(to, bio, i) { | 318 | bio_for_each_segment_all(to, bio, i, iter_all) { |
317 | struct page *page = to->bv_page; | 319 | struct page *page = to->bv_page; |
318 | 320 | ||
319 | if (page_to_pfn(page) <= q->limits.bounce_pfn) | 321 | if (page_to_pfn(page) <= q->limits.bounce_pfn) |
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index 23cb1dc7296b..64def336f053 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c | |||
@@ -432,8 +432,9 @@ static void do_btree_node_write(struct btree *b) | |||
432 | int j; | 432 | int j; |
433 | struct bio_vec *bv; | 433 | struct bio_vec *bv; |
434 | void *base = (void *) ((unsigned long) i & ~(PAGE_SIZE - 1)); | 434 | void *base = (void *) ((unsigned long) i & ~(PAGE_SIZE - 1)); |
435 | struct bvec_iter_all iter_all; | ||
435 | 436 | ||
436 | bio_for_each_segment_all(bv, b->bio, j) | 437 | bio_for_each_segment_all(bv, b->bio, j, iter_all) |
437 | memcpy(page_address(bv->bv_page), | 438 | memcpy(page_address(bv->bv_page), |
438 | base + j * PAGE_SIZE, PAGE_SIZE); | 439 | base + j * PAGE_SIZE, PAGE_SIZE); |
439 | 440 | ||
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 47d4e0d30bf0..9a29037f5615 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
@@ -1447,8 +1447,9 @@ static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone) | |||
1447 | { | 1447 | { |
1448 | unsigned int i; | 1448 | unsigned int i; |
1449 | struct bio_vec *bv; | 1449 | struct bio_vec *bv; |
1450 | struct bvec_iter_all iter_all; | ||
1450 | 1451 | ||
1451 | bio_for_each_segment_all(bv, clone, i) { | 1452 | bio_for_each_segment_all(bv, clone, i, iter_all) { |
1452 | BUG_ON(!bv->bv_page); | 1453 | BUG_ON(!bv->bv_page); |
1453 | mempool_free(bv->bv_page, &cc->page_pool); | 1454 | mempool_free(bv->bv_page, &cc->page_pool); |
1454 | } | 1455 | } |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 7e63ccc4ae7b..88c61d3090b0 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -2112,13 +2112,14 @@ static void process_checks(struct r1bio *r1_bio) | |||
2112 | struct page **spages = get_resync_pages(sbio)->pages; | 2112 | struct page **spages = get_resync_pages(sbio)->pages; |
2113 | struct bio_vec *bi; | 2113 | struct bio_vec *bi; |
2114 | int page_len[RESYNC_PAGES] = { 0 }; | 2114 | int page_len[RESYNC_PAGES] = { 0 }; |
2115 | struct bvec_iter_all iter_all; | ||
2115 | 2116 | ||
2116 | if (sbio->bi_end_io != end_sync_read) | 2117 | if (sbio->bi_end_io != end_sync_read) |
2117 | continue; | 2118 | continue; |
2118 | /* Now we can 'fixup' the error value */ | 2119 | /* Now we can 'fixup' the error value */ |
2119 | sbio->bi_status = 0; | 2120 | sbio->bi_status = 0; |
2120 | 2121 | ||
2121 | bio_for_each_segment_all(bi, sbio, j) | 2122 | bio_for_each_segment_all(bi, sbio, j, iter_all) |
2122 | page_len[j] = bi->bv_len; | 2123 | page_len[j] = bi->bv_len; |
2123 | 2124 | ||
2124 | if (!status) { | 2125 | if (!status) { |
diff --git a/drivers/staging/erofs/data.c b/drivers/staging/erofs/data.c index 5a55f0bfdfbb..4871ba7b7d9a 100644 --- a/drivers/staging/erofs/data.c +++ b/drivers/staging/erofs/data.c | |||
@@ -20,8 +20,9 @@ static inline void read_endio(struct bio *bio) | |||
20 | int i; | 20 | int i; |
21 | struct bio_vec *bvec; | 21 | struct bio_vec *bvec; |
22 | const blk_status_t err = bio->bi_status; | 22 | const blk_status_t err = bio->bi_status; |
23 | struct bvec_iter_all iter_all; | ||
23 | 24 | ||
24 | bio_for_each_segment_all(bvec, bio, i) { | 25 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
25 | struct page *page = bvec->bv_page; | 26 | struct page *page = bvec->bv_page; |
26 | 27 | ||
27 | /* page is already locked */ | 28 | /* page is already locked */ |
diff --git a/drivers/staging/erofs/unzip_vle.c b/drivers/staging/erofs/unzip_vle.c index 4ac1099a39c6..c057c5616b1d 100644 --- a/drivers/staging/erofs/unzip_vle.c +++ b/drivers/staging/erofs/unzip_vle.c | |||
@@ -830,8 +830,9 @@ static inline void z_erofs_vle_read_endio(struct bio *bio) | |||
830 | #ifdef EROFS_FS_HAS_MANAGED_CACHE | 830 | #ifdef EROFS_FS_HAS_MANAGED_CACHE |
831 | struct address_space *mc = NULL; | 831 | struct address_space *mc = NULL; |
832 | #endif | 832 | #endif |
833 | struct bvec_iter_all iter_all; | ||
833 | 834 | ||
834 | bio_for_each_segment_all(bvec, bio, i) { | 835 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
835 | struct page *page = bvec->bv_page; | 836 | struct page *page = bvec->bv_page; |
836 | bool cachemngd = false; | 837 | bool cachemngd = false; |
837 | 838 | ||
diff --git a/fs/block_dev.c b/fs/block_dev.c index 58a4c1217fa8..7758adee6efe 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -211,6 +211,7 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter, | |||
211 | ssize_t ret; | 211 | ssize_t ret; |
212 | blk_qc_t qc; | 212 | blk_qc_t qc; |
213 | int i; | 213 | int i; |
214 | struct bvec_iter_all iter_all; | ||
214 | 215 | ||
215 | if ((pos | iov_iter_alignment(iter)) & | 216 | if ((pos | iov_iter_alignment(iter)) & |
216 | (bdev_logical_block_size(bdev) - 1)) | 217 | (bdev_logical_block_size(bdev) - 1)) |
@@ -260,7 +261,7 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter, | |||
260 | } | 261 | } |
261 | __set_current_state(TASK_RUNNING); | 262 | __set_current_state(TASK_RUNNING); |
262 | 263 | ||
263 | bio_for_each_segment_all(bvec, &bio, i) { | 264 | bio_for_each_segment_all(bvec, &bio, i, iter_all) { |
264 | if (should_dirty && !PageCompound(bvec->bv_page)) | 265 | if (should_dirty && !PageCompound(bvec->bv_page)) |
265 | set_page_dirty_lock(bvec->bv_page); | 266 | set_page_dirty_lock(bvec->bv_page); |
266 | put_page(bvec->bv_page); | 267 | put_page(bvec->bv_page); |
@@ -329,8 +330,9 @@ static void blkdev_bio_end_io(struct bio *bio) | |||
329 | } else { | 330 | } else { |
330 | struct bio_vec *bvec; | 331 | struct bio_vec *bvec; |
331 | int i; | 332 | int i; |
333 | struct bvec_iter_all iter_all; | ||
332 | 334 | ||
333 | bio_for_each_segment_all(bvec, bio, i) | 335 | bio_for_each_segment_all(bvec, bio, i, iter_all) |
334 | put_page(bvec->bv_page); | 336 | put_page(bvec->bv_page); |
335 | bio_put(bio); | 337 | bio_put(bio); |
336 | } | 338 | } |
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 548057630b69..6896ea60c843 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
@@ -162,13 +162,14 @@ csum_failed: | |||
162 | } else { | 162 | } else { |
163 | int i; | 163 | int i; |
164 | struct bio_vec *bvec; | 164 | struct bio_vec *bvec; |
165 | struct bvec_iter_all iter_all; | ||
165 | 166 | ||
166 | /* | 167 | /* |
167 | * we have verified the checksum already, set page | 168 | * we have verified the checksum already, set page |
168 | * checked so the end_io handlers know about it | 169 | * checked so the end_io handlers know about it |
169 | */ | 170 | */ |
170 | ASSERT(!bio_flagged(bio, BIO_CLONED)); | 171 | ASSERT(!bio_flagged(bio, BIO_CLONED)); |
171 | bio_for_each_segment_all(bvec, cb->orig_bio, i) | 172 | bio_for_each_segment_all(bvec, cb->orig_bio, i, iter_all) |
172 | SetPageChecked(bvec->bv_page); | 173 | SetPageChecked(bvec->bv_page); |
173 | 174 | ||
174 | bio_endio(cb->orig_bio); | 175 | bio_endio(cb->orig_bio); |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 6a2a2a951705..ca1b7da6dd1b 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -832,9 +832,10 @@ static blk_status_t btree_csum_one_bio(struct bio *bio) | |||
832 | struct bio_vec *bvec; | 832 | struct bio_vec *bvec; |
833 | struct btrfs_root *root; | 833 | struct btrfs_root *root; |
834 | int i, ret = 0; | 834 | int i, ret = 0; |
835 | struct bvec_iter_all iter_all; | ||
835 | 836 | ||
836 | ASSERT(!bio_flagged(bio, BIO_CLONED)); | 837 | ASSERT(!bio_flagged(bio, BIO_CLONED)); |
837 | bio_for_each_segment_all(bvec, bio, i) { | 838 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
838 | root = BTRFS_I(bvec->bv_page->mapping->host)->root; | 839 | root = BTRFS_I(bvec->bv_page->mapping->host)->root; |
839 | ret = csum_dirty_buffer(root->fs_info, bvec->bv_page); | 840 | ret = csum_dirty_buffer(root->fs_info, bvec->bv_page); |
840 | if (ret) | 841 | if (ret) |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 986ef49b0269..4ed58c9a94a9 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -2422,9 +2422,10 @@ static void end_bio_extent_writepage(struct bio *bio) | |||
2422 | u64 start; | 2422 | u64 start; |
2423 | u64 end; | 2423 | u64 end; |
2424 | int i; | 2424 | int i; |
2425 | struct bvec_iter_all iter_all; | ||
2425 | 2426 | ||
2426 | ASSERT(!bio_flagged(bio, BIO_CLONED)); | 2427 | ASSERT(!bio_flagged(bio, BIO_CLONED)); |
2427 | bio_for_each_segment_all(bvec, bio, i) { | 2428 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
2428 | struct page *page = bvec->bv_page; | 2429 | struct page *page = bvec->bv_page; |
2429 | struct inode *inode = page->mapping->host; | 2430 | struct inode *inode = page->mapping->host; |
2430 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); | 2431 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); |
@@ -2493,9 +2494,10 @@ static void end_bio_extent_readpage(struct bio *bio) | |||
2493 | int mirror; | 2494 | int mirror; |
2494 | int ret; | 2495 | int ret; |
2495 | int i; | 2496 | int i; |
2497 | struct bvec_iter_all iter_all; | ||
2496 | 2498 | ||
2497 | ASSERT(!bio_flagged(bio, BIO_CLONED)); | 2499 | ASSERT(!bio_flagged(bio, BIO_CLONED)); |
2498 | bio_for_each_segment_all(bvec, bio, i) { | 2500 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
2499 | struct page *page = bvec->bv_page; | 2501 | struct page *page = bvec->bv_page; |
2500 | struct inode *inode = page->mapping->host; | 2502 | struct inode *inode = page->mapping->host; |
2501 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); | 2503 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); |
@@ -3635,9 +3637,10 @@ static void end_bio_extent_buffer_writepage(struct bio *bio) | |||
3635 | struct bio_vec *bvec; | 3637 | struct bio_vec *bvec; |
3636 | struct extent_buffer *eb; | 3638 | struct extent_buffer *eb; |
3637 | int i, done; | 3639 | int i, done; |
3640 | struct bvec_iter_all iter_all; | ||
3638 | 3641 | ||
3639 | ASSERT(!bio_flagged(bio, BIO_CLONED)); | 3642 | ASSERT(!bio_flagged(bio, BIO_CLONED)); |
3640 | bio_for_each_segment_all(bvec, bio, i) { | 3643 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
3641 | struct page *page = bvec->bv_page; | 3644 | struct page *page = bvec->bv_page; |
3642 | 3645 | ||
3643 | eb = (struct extent_buffer *)page->private; | 3646 | eb = (struct extent_buffer *)page->private; |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 5c349667c761..7ade5769f691 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -7777,6 +7777,7 @@ static void btrfs_retry_endio_nocsum(struct bio *bio) | |||
7777 | struct bio_vec *bvec; | 7777 | struct bio_vec *bvec; |
7778 | struct extent_io_tree *io_tree, *failure_tree; | 7778 | struct extent_io_tree *io_tree, *failure_tree; |
7779 | int i; | 7779 | int i; |
7780 | struct bvec_iter_all iter_all; | ||
7780 | 7781 | ||
7781 | if (bio->bi_status) | 7782 | if (bio->bi_status) |
7782 | goto end; | 7783 | goto end; |
@@ -7788,7 +7789,7 @@ static void btrfs_retry_endio_nocsum(struct bio *bio) | |||
7788 | 7789 | ||
7789 | done->uptodate = 1; | 7790 | done->uptodate = 1; |
7790 | ASSERT(!bio_flagged(bio, BIO_CLONED)); | 7791 | ASSERT(!bio_flagged(bio, BIO_CLONED)); |
7791 | bio_for_each_segment_all(bvec, bio, i) | 7792 | bio_for_each_segment_all(bvec, bio, i, iter_all) |
7792 | clean_io_failure(BTRFS_I(inode)->root->fs_info, failure_tree, | 7793 | clean_io_failure(BTRFS_I(inode)->root->fs_info, failure_tree, |
7793 | io_tree, done->start, bvec->bv_page, | 7794 | io_tree, done->start, bvec->bv_page, |
7794 | btrfs_ino(BTRFS_I(inode)), 0); | 7795 | btrfs_ino(BTRFS_I(inode)), 0); |
@@ -7867,6 +7868,7 @@ static void btrfs_retry_endio(struct bio *bio) | |||
7867 | int uptodate; | 7868 | int uptodate; |
7868 | int ret; | 7869 | int ret; |
7869 | int i; | 7870 | int i; |
7871 | struct bvec_iter_all iter_all; | ||
7870 | 7872 | ||
7871 | if (bio->bi_status) | 7873 | if (bio->bi_status) |
7872 | goto end; | 7874 | goto end; |
@@ -7880,7 +7882,7 @@ static void btrfs_retry_endio(struct bio *bio) | |||
7880 | failure_tree = &BTRFS_I(inode)->io_failure_tree; | 7882 | failure_tree = &BTRFS_I(inode)->io_failure_tree; |
7881 | 7883 | ||
7882 | ASSERT(!bio_flagged(bio, BIO_CLONED)); | 7884 | ASSERT(!bio_flagged(bio, BIO_CLONED)); |
7883 | bio_for_each_segment_all(bvec, bio, i) { | 7885 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
7884 | ret = __readpage_endio_check(inode, io_bio, i, bvec->bv_page, | 7886 | ret = __readpage_endio_check(inode, io_bio, i, bvec->bv_page, |
7885 | bvec->bv_offset, done->start, | 7887 | bvec->bv_offset, done->start, |
7886 | bvec->bv_len); | 7888 | bvec->bv_len); |
diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c index e74455eb42f9..1869ba8e5981 100644 --- a/fs/btrfs/raid56.c +++ b/fs/btrfs/raid56.c | |||
@@ -1443,10 +1443,11 @@ static void set_bio_pages_uptodate(struct bio *bio) | |||
1443 | { | 1443 | { |
1444 | struct bio_vec *bvec; | 1444 | struct bio_vec *bvec; |
1445 | int i; | 1445 | int i; |
1446 | struct bvec_iter_all iter_all; | ||
1446 | 1447 | ||
1447 | ASSERT(!bio_flagged(bio, BIO_CLONED)); | 1448 | ASSERT(!bio_flagged(bio, BIO_CLONED)); |
1448 | 1449 | ||
1449 | bio_for_each_segment_all(bvec, bio, i) | 1450 | bio_for_each_segment_all(bvec, bio, i, iter_all) |
1450 | SetPageUptodate(bvec->bv_page); | 1451 | SetPageUptodate(bvec->bv_page); |
1451 | } | 1452 | } |
1452 | 1453 | ||
diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c index 0959044c5cee..5759bcd018cd 100644 --- a/fs/crypto/bio.c +++ b/fs/crypto/bio.c | |||
@@ -30,8 +30,9 @@ static void __fscrypt_decrypt_bio(struct bio *bio, bool done) | |||
30 | { | 30 | { |
31 | struct bio_vec *bv; | 31 | struct bio_vec *bv; |
32 | int i; | 32 | int i; |
33 | struct bvec_iter_all iter_all; | ||
33 | 34 | ||
34 | bio_for_each_segment_all(bv, bio, i) { | 35 | bio_for_each_segment_all(bv, bio, i, iter_all) { |
35 | struct page *page = bv->bv_page; | 36 | struct page *page = bv->bv_page; |
36 | int ret = fscrypt_decrypt_page(page->mapping->host, page, | 37 | int ret = fscrypt_decrypt_page(page->mapping->host, page, |
37 | PAGE_SIZE, 0, page->index); | 38 | PAGE_SIZE, 0, page->index); |
diff --git a/fs/direct-io.c b/fs/direct-io.c index ec2fb6fe6d37..9bb015bc4a83 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
@@ -551,7 +551,9 @@ static blk_status_t dio_bio_complete(struct dio *dio, struct bio *bio) | |||
551 | if (dio->is_async && dio->op == REQ_OP_READ && dio->should_dirty) { | 551 | if (dio->is_async && dio->op == REQ_OP_READ && dio->should_dirty) { |
552 | bio_check_pages_dirty(bio); /* transfers ownership */ | 552 | bio_check_pages_dirty(bio); /* transfers ownership */ |
553 | } else { | 553 | } else { |
554 | bio_for_each_segment_all(bvec, bio, i) { | 554 | struct bvec_iter_all iter_all; |
555 | |||
556 | bio_for_each_segment_all(bvec, bio, i, iter_all) { | ||
555 | struct page *page = bvec->bv_page; | 557 | struct page *page = bvec->bv_page; |
556 | 558 | ||
557 | if (dio->op == REQ_OP_READ && !PageCompound(page) && | 559 | if (dio->op == REQ_OP_READ && !PageCompound(page) && |
diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c index 5331a15a61f1..24a8e34882e9 100644 --- a/fs/exofs/ore.c +++ b/fs/exofs/ore.c | |||
@@ -420,8 +420,9 @@ static void _clear_bio(struct bio *bio) | |||
420 | { | 420 | { |
421 | struct bio_vec *bv; | 421 | struct bio_vec *bv; |
422 | unsigned i; | 422 | unsigned i; |
423 | struct bvec_iter_all iter_all; | ||
423 | 424 | ||
424 | bio_for_each_segment_all(bv, bio, i) { | 425 | bio_for_each_segment_all(bv, bio, i, iter_all) { |
425 | unsigned this_count = bv->bv_len; | 426 | unsigned this_count = bv->bv_len; |
426 | 427 | ||
427 | if (likely(PAGE_SIZE == this_count)) | 428 | if (likely(PAGE_SIZE == this_count)) |
diff --git a/fs/exofs/ore_raid.c b/fs/exofs/ore_raid.c index 199590f36203..e83bab54b03e 100644 --- a/fs/exofs/ore_raid.c +++ b/fs/exofs/ore_raid.c | |||
@@ -468,11 +468,12 @@ static void _mark_read4write_pages_uptodate(struct ore_io_state *ios, int ret) | |||
468 | /* loop on all devices all pages */ | 468 | /* loop on all devices all pages */ |
469 | for (d = 0; d < ios->numdevs; d++) { | 469 | for (d = 0; d < ios->numdevs; d++) { |
470 | struct bio *bio = ios->per_dev[d].bio; | 470 | struct bio *bio = ios->per_dev[d].bio; |
471 | struct bvec_iter_all iter_all; | ||
471 | 472 | ||
472 | if (!bio) | 473 | if (!bio) |
473 | continue; | 474 | continue; |
474 | 475 | ||
475 | bio_for_each_segment_all(bv, bio, i) { | 476 | bio_for_each_segment_all(bv, bio, i, iter_all) { |
476 | struct page *page = bv->bv_page; | 477 | struct page *page = bv->bv_page; |
477 | 478 | ||
478 | SetPageUptodate(page); | 479 | SetPageUptodate(page); |
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 2aa62d58d8dd..cff4c4aa7a9c 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c | |||
@@ -63,8 +63,9 @@ static void ext4_finish_bio(struct bio *bio) | |||
63 | { | 63 | { |
64 | int i; | 64 | int i; |
65 | struct bio_vec *bvec; | 65 | struct bio_vec *bvec; |
66 | struct bvec_iter_all iter_all; | ||
66 | 67 | ||
67 | bio_for_each_segment_all(bvec, bio, i) { | 68 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
68 | struct page *page = bvec->bv_page; | 69 | struct page *page = bvec->bv_page; |
69 | #ifdef CONFIG_EXT4_FS_ENCRYPTION | 70 | #ifdef CONFIG_EXT4_FS_ENCRYPTION |
70 | struct page *data_page = NULL; | 71 | struct page *data_page = NULL; |
diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c index 6aa282ee455a..e53639784892 100644 --- a/fs/ext4/readpage.c +++ b/fs/ext4/readpage.c | |||
@@ -72,6 +72,7 @@ static void mpage_end_io(struct bio *bio) | |||
72 | { | 72 | { |
73 | struct bio_vec *bv; | 73 | struct bio_vec *bv; |
74 | int i; | 74 | int i; |
75 | struct bvec_iter_all iter_all; | ||
75 | 76 | ||
76 | if (ext4_bio_encrypted(bio)) { | 77 | if (ext4_bio_encrypted(bio)) { |
77 | if (bio->bi_status) { | 78 | if (bio->bi_status) { |
@@ -81,7 +82,7 @@ static void mpage_end_io(struct bio *bio) | |||
81 | return; | 82 | return; |
82 | } | 83 | } |
83 | } | 84 | } |
84 | bio_for_each_segment_all(bv, bio, i) { | 85 | bio_for_each_segment_all(bv, bio, i, iter_all) { |
85 | struct page *page = bv->bv_page; | 86 | struct page *page = bv->bv_page; |
86 | 87 | ||
87 | if (!bio->bi_status) { | 88 | if (!bio->bi_status) { |
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index f91d8630c9a2..da060b77f64d 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c | |||
@@ -87,8 +87,9 @@ static void __read_end_io(struct bio *bio) | |||
87 | struct page *page; | 87 | struct page *page; |
88 | struct bio_vec *bv; | 88 | struct bio_vec *bv; |
89 | int i; | 89 | int i; |
90 | struct bvec_iter_all iter_all; | ||
90 | 91 | ||
91 | bio_for_each_segment_all(bv, bio, i) { | 92 | bio_for_each_segment_all(bv, bio, i, iter_all) { |
92 | page = bv->bv_page; | 93 | page = bv->bv_page; |
93 | 94 | ||
94 | /* PG_error was set if any post_read step failed */ | 95 | /* PG_error was set if any post_read step failed */ |
@@ -164,13 +165,14 @@ static void f2fs_write_end_io(struct bio *bio) | |||
164 | struct f2fs_sb_info *sbi = bio->bi_private; | 165 | struct f2fs_sb_info *sbi = bio->bi_private; |
165 | struct bio_vec *bvec; | 166 | struct bio_vec *bvec; |
166 | int i; | 167 | int i; |
168 | struct bvec_iter_all iter_all; | ||
167 | 169 | ||
168 | if (time_to_inject(sbi, FAULT_WRITE_IO)) { | 170 | if (time_to_inject(sbi, FAULT_WRITE_IO)) { |
169 | f2fs_show_injection_info(FAULT_WRITE_IO); | 171 | f2fs_show_injection_info(FAULT_WRITE_IO); |
170 | bio->bi_status = BLK_STS_IOERR; | 172 | bio->bi_status = BLK_STS_IOERR; |
171 | } | 173 | } |
172 | 174 | ||
173 | bio_for_each_segment_all(bvec, bio, i) { | 175 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
174 | struct page *page = bvec->bv_page; | 176 | struct page *page = bvec->bv_page; |
175 | enum count_type type = WB_DATA_TYPE(page); | 177 | enum count_type type = WB_DATA_TYPE(page); |
176 | 178 | ||
@@ -347,6 +349,7 @@ static bool __has_merged_page(struct f2fs_bio_info *io, struct inode *inode, | |||
347 | struct bio_vec *bvec; | 349 | struct bio_vec *bvec; |
348 | struct page *target; | 350 | struct page *target; |
349 | int i; | 351 | int i; |
352 | struct bvec_iter_all iter_all; | ||
350 | 353 | ||
351 | if (!io->bio) | 354 | if (!io->bio) |
352 | return false; | 355 | return false; |
@@ -354,7 +357,7 @@ static bool __has_merged_page(struct f2fs_bio_info *io, struct inode *inode, | |||
354 | if (!inode && !page && !ino) | 357 | if (!inode && !page && !ino) |
355 | return true; | 358 | return true; |
356 | 359 | ||
357 | bio_for_each_segment_all(bvec, io->bio, i) { | 360 | bio_for_each_segment_all(bvec, io->bio, i, iter_all) { |
358 | 361 | ||
359 | if (bvec->bv_page->mapping) | 362 | if (bvec->bv_page->mapping) |
360 | target = bvec->bv_page; | 363 | target = bvec->bv_page; |
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 94dcab655bc0..15deefeaafd0 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
@@ -170,7 +170,8 @@ u64 gfs2_log_bmap(struct gfs2_sbd *sdp) | |||
170 | * that is pinned in the pagecache. | 170 | * that is pinned in the pagecache. |
171 | */ | 171 | */ |
172 | 172 | ||
173 | static void gfs2_end_log_write_bh(struct gfs2_sbd *sdp, struct bio_vec *bvec, | 173 | static void gfs2_end_log_write_bh(struct gfs2_sbd *sdp, |
174 | struct bio_vec *bvec, | ||
174 | blk_status_t error) | 175 | blk_status_t error) |
175 | { | 176 | { |
176 | struct buffer_head *bh, *next; | 177 | struct buffer_head *bh, *next; |
@@ -208,6 +209,7 @@ static void gfs2_end_log_write(struct bio *bio) | |||
208 | struct bio_vec *bvec; | 209 | struct bio_vec *bvec; |
209 | struct page *page; | 210 | struct page *page; |
210 | int i; | 211 | int i; |
212 | struct bvec_iter_all iter_all; | ||
211 | 213 | ||
212 | if (bio->bi_status) { | 214 | if (bio->bi_status) { |
213 | fs_err(sdp, "Error %d writing to journal, jid=%u\n", | 215 | fs_err(sdp, "Error %d writing to journal, jid=%u\n", |
@@ -215,7 +217,7 @@ static void gfs2_end_log_write(struct bio *bio) | |||
215 | wake_up(&sdp->sd_logd_waitq); | 217 | wake_up(&sdp->sd_logd_waitq); |
216 | } | 218 | } |
217 | 219 | ||
218 | bio_for_each_segment_all(bvec, bio, i) { | 220 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
219 | page = bvec->bv_page; | 221 | page = bvec->bv_page; |
220 | if (page_has_buffers(page)) | 222 | if (page_has_buffers(page)) |
221 | gfs2_end_log_write_bh(sdp, bvec, bio->bi_status); | 223 | gfs2_end_log_write_bh(sdp, bvec, bio->bi_status); |
@@ -388,8 +390,9 @@ static void gfs2_end_log_read(struct bio *bio) | |||
388 | struct page *page; | 390 | struct page *page; |
389 | struct bio_vec *bvec; | 391 | struct bio_vec *bvec; |
390 | int i; | 392 | int i; |
393 | struct bvec_iter_all iter_all; | ||
391 | 394 | ||
392 | bio_for_each_segment_all(bvec, bio, i) { | 395 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
393 | page = bvec->bv_page; | 396 | page = bvec->bv_page; |
394 | if (bio->bi_status) { | 397 | if (bio->bi_status) { |
395 | int err = blk_status_to_errno(bio->bi_status); | 398 | int err = blk_status_to_errno(bio->bi_status); |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index be9c0bf697fe..3201342404a7 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -190,8 +190,9 @@ static void gfs2_meta_read_endio(struct bio *bio) | |||
190 | { | 190 | { |
191 | struct bio_vec *bvec; | 191 | struct bio_vec *bvec; |
192 | int i; | 192 | int i; |
193 | struct bvec_iter_all iter_all; | ||
193 | 194 | ||
194 | bio_for_each_segment_all(bvec, bio, i) { | 195 | bio_for_each_segment_all(bvec, bio, i, iter_all) { |
195 | struct page *page = bvec->bv_page; | 196 | struct page *page = bvec->bv_page; |
196 | struct buffer_head *bh = page_buffers(page); | 197 | struct buffer_head *bh = page_buffers(page); |
197 | unsigned int len = bvec->bv_len; | 198 | unsigned int len = bvec->bv_len; |
diff --git a/fs/iomap.c b/fs/iomap.c index a3088fae567b..af736acd9006 100644 --- a/fs/iomap.c +++ b/fs/iomap.c | |||
@@ -267,8 +267,9 @@ iomap_read_end_io(struct bio *bio) | |||
267 | int error = blk_status_to_errno(bio->bi_status); | 267 | int error = blk_status_to_errno(bio->bi_status); |
268 | struct bio_vec *bvec; | 268 | struct bio_vec *bvec; |
269 | int i; | 269 | int i; |
270 | struct bvec_iter_all iter_all; | ||
270 | 271 | ||
271 | bio_for_each_segment_all(bvec, bio, i) | 272 | bio_for_each_segment_all(bvec, bio, i, iter_all) |
272 | iomap_read_page_end_io(bvec, error); | 273 | iomap_read_page_end_io(bvec, error); |
273 | bio_put(bio); | 274 | bio_put(bio); |
274 | } | 275 | } |
@@ -1559,8 +1560,9 @@ static void iomap_dio_bio_end_io(struct bio *bio) | |||
1559 | } else { | 1560 | } else { |
1560 | struct bio_vec *bvec; | 1561 | struct bio_vec *bvec; |
1561 | int i; | 1562 | int i; |
1563 | struct bvec_iter_all iter_all; | ||
1562 | 1564 | ||
1563 | bio_for_each_segment_all(bvec, bio, i) | 1565 | bio_for_each_segment_all(bvec, bio, i, iter_all) |
1564 | put_page(bvec->bv_page); | 1566 | put_page(bvec->bv_page); |
1565 | bio_put(bio); | 1567 | bio_put(bio); |
1566 | } | 1568 | } |
diff --git a/fs/mpage.c b/fs/mpage.c index c820dc9bebab..3f19da75178b 100644 --- a/fs/mpage.c +++ b/fs/mpage.c | |||
@@ -48,8 +48,9 @@ static void mpage_end_io(struct bio *bio) | |||
48 | { | 48 | { |
49 | struct bio_vec *bv; | 49 | struct bio_vec *bv; |
50 | int i; | 50 | int i; |
51 | struct bvec_iter_all iter_all; | ||
51 | 52 | ||
52 | bio_for_each_segment_all(bv, bio, i) { | 53 | bio_for_each_segment_all(bv, bio, i, iter_all) { |
53 | struct page *page = bv->bv_page; | 54 | struct page *page = bv->bv_page; |
54 | page_endio(page, bio_op(bio), | 55 | page_endio(page, bio_op(bio), |
55 | blk_status_to_errno(bio->bi_status)); | 56 | blk_status_to_errno(bio->bi_status)); |
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 338b9d9984e0..1f1829e506e8 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c | |||
@@ -62,7 +62,7 @@ xfs_find_daxdev_for_inode( | |||
62 | static void | 62 | static void |
63 | xfs_finish_page_writeback( | 63 | xfs_finish_page_writeback( |
64 | struct inode *inode, | 64 | struct inode *inode, |
65 | struct bio_vec *bvec, | 65 | struct bio_vec *bvec, |
66 | int error) | 66 | int error) |
67 | { | 67 | { |
68 | struct iomap_page *iop = to_iomap_page(bvec->bv_page); | 68 | struct iomap_page *iop = to_iomap_page(bvec->bv_page); |
@@ -98,6 +98,7 @@ xfs_destroy_ioend( | |||
98 | for (bio = &ioend->io_inline_bio; bio; bio = next) { | 98 | for (bio = &ioend->io_inline_bio; bio; bio = next) { |
99 | struct bio_vec *bvec; | 99 | struct bio_vec *bvec; |
100 | int i; | 100 | int i; |
101 | struct bvec_iter_all iter_all; | ||
101 | 102 | ||
102 | /* | 103 | /* |
103 | * For the last bio, bi_private points to the ioend, so we | 104 | * For the last bio, bi_private points to the ioend, so we |
@@ -109,7 +110,7 @@ xfs_destroy_ioend( | |||
109 | next = bio->bi_private; | 110 | next = bio->bi_private; |
110 | 111 | ||
111 | /* walk each page on bio, ending page IO on them */ | 112 | /* walk each page on bio, ending page IO on them */ |
112 | bio_for_each_segment_all(bvec, bio, i) | 113 | bio_for_each_segment_all(bvec, bio, i, iter_all) |
113 | xfs_finish_page_writeback(inode, bvec, error); | 114 | xfs_finish_page_writeback(inode, bvec, error); |
114 | bio_put(bio); | 115 | bio_put(bio); |
115 | } | 116 | } |
diff --git a/include/linux/bio.h b/include/linux/bio.h index 7ef8a7505c0a..089370eb84d9 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
@@ -128,12 +128,19 @@ static inline bool bio_full(struct bio *bio) | |||
128 | return bio->bi_vcnt >= bio->bi_max_vecs; | 128 | return bio->bi_vcnt >= bio->bi_max_vecs; |
129 | } | 129 | } |
130 | 130 | ||
131 | #define mp_bvec_for_each_segment(bv, bvl, i, iter_all) \ | ||
132 | for (bv = bvec_init_iter_all(&iter_all); \ | ||
133 | (iter_all.done < (bvl)->bv_len) && \ | ||
134 | (mp_bvec_next_segment((bvl), &iter_all), 1); \ | ||
135 | iter_all.done += bv->bv_len, i += 1) | ||
136 | |||
131 | /* | 137 | /* |
132 | * drivers should _never_ use the all version - the bio may have been split | 138 | * drivers should _never_ use the all version - the bio may have been split |
133 | * before it got to the driver and the driver won't own all of it | 139 | * before it got to the driver and the driver won't own all of it |
134 | */ | 140 | */ |
135 | #define bio_for_each_segment_all(bvl, bio, i) \ | 141 | #define bio_for_each_segment_all(bvl, bio, i, iter_all) \ |
136 | for (i = 0, bvl = (bio)->bi_io_vec; i < (bio)->bi_vcnt; i++, bvl++) | 142 | for (i = 0, iter_all.idx = 0; iter_all.idx < (bio)->bi_vcnt; iter_all.idx++) \ |
143 | mp_bvec_for_each_segment(bvl, &((bio)->bi_io_vec[iter_all.idx]), i, iter_all) | ||
137 | 144 | ||
138 | static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter, | 145 | static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter, |
139 | unsigned bytes) | 146 | unsigned bytes) |
diff --git a/include/linux/bvec.h b/include/linux/bvec.h index 21f76bad7be2..30a57b68d017 100644 --- a/include/linux/bvec.h +++ b/include/linux/bvec.h | |||
@@ -45,6 +45,12 @@ struct bvec_iter { | |||
45 | current bvec */ | 45 | current bvec */ |
46 | }; | 46 | }; |
47 | 47 | ||
48 | struct bvec_iter_all { | ||
49 | struct bio_vec bv; | ||
50 | int idx; | ||
51 | unsigned done; | ||
52 | }; | ||
53 | |||
48 | /* | 54 | /* |
49 | * various member access, note that bio_data should of course not be used | 55 | * various member access, note that bio_data should of course not be used |
50 | * on highmem page vectors | 56 | * on highmem page vectors |
@@ -131,6 +137,30 @@ static inline bool bvec_iter_advance(const struct bio_vec *bv, | |||
131 | .bi_bvec_done = 0, \ | 137 | .bi_bvec_done = 0, \ |
132 | } | 138 | } |
133 | 139 | ||
140 | static inline struct bio_vec *bvec_init_iter_all(struct bvec_iter_all *iter_all) | ||
141 | { | ||
142 | iter_all->bv.bv_page = NULL; | ||
143 | iter_all->done = 0; | ||
144 | |||
145 | return &iter_all->bv; | ||
146 | } | ||
147 | |||
148 | static inline void mp_bvec_next_segment(const struct bio_vec *bvec, | ||
149 | struct bvec_iter_all *iter_all) | ||
150 | { | ||
151 | struct bio_vec *bv = &iter_all->bv; | ||
152 | |||
153 | if (bv->bv_page) { | ||
154 | bv->bv_page = nth_page(bv->bv_page, 1); | ||
155 | bv->bv_offset = 0; | ||
156 | } else { | ||
157 | bv->bv_page = bvec->bv_page; | ||
158 | bv->bv_offset = bvec->bv_offset; | ||
159 | } | ||
160 | bv->bv_len = min_t(unsigned int, PAGE_SIZE - bv->bv_offset, | ||
161 | bvec->bv_len - iter_all->done); | ||
162 | } | ||
163 | |||
134 | /* | 164 | /* |
135 | * Get the last single-page segment from the multi-page bvec and store it | 165 | * Get the last single-page segment from the multi-page bvec and store it |
136 | * in @seg | 166 | * in @seg |