Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

block: Add bio_for_each_segment_all()

__bio_for_each_segment() iterates bvecs from the specified index
instead of bio->bv_idx. Currently, the only usage is to walk all the
bvecs after the bio has been advanced by specifying 0 index.

For immutable bvecs, we need to split these apart;
bio_for_each_segment() is going to have a different implementation.
This will also help document the intent of code that's using it -
bio_for_each_segment_all() is only legal to use for code that owns the
bio.

Signed-off-by: Kent Overstreet <koverstreet@google.com>
CC: Jens Axboe <axboe@kernel.dk>
CC: Neil Brown <neilb@suse.de>
CC: Boaz Harrosh <bharrosh@panasas.com>

+25 -14
+1 -1
drivers/block/rbd.c
··· 952 952 /* Find first affected segment... */ 953 953 954 954 resid = offset; 955 - __bio_for_each_segment(bv, bio_src, idx, 0) { 955 + bio_for_each_segment(bv, bio_src, idx) { 956 956 if (resid < bv->bv_len) 957 957 break; 958 958 resid -= bv->bv_len;
+1 -1
drivers/md/raid1.c
··· 1291 1291 * know the original bi_idx, so we just free 1292 1292 * them all 1293 1293 */ 1294 - __bio_for_each_segment(bvec, mbio, j, 0) 1294 + bio_for_each_segment_all(bvec, mbio, j) 1295 1295 bvec->bv_page = r1_bio->behind_bvecs[j].bv_page; 1296 1296 if (test_bit(WriteMostly, &conf->mirrors[i].rdev->flags)) 1297 1297 atomic_inc(&r1_bio->behind_remaining);
+6 -6
fs/bio.c
··· 961 961 int iov_idx = 0; 962 962 unsigned int iov_off = 0; 963 963 964 - __bio_for_each_segment(bvec, bio, i, 0) { 964 + bio_for_each_segment_all(bvec, bio, i) { 965 965 char *bv_addr = page_address(bvec->bv_page); 966 966 unsigned int bv_len = iovecs[i].bv_len; 967 967 ··· 1143 1143 return bio; 1144 1144 cleanup: 1145 1145 if (!map_data) 1146 - bio_for_each_segment(bvec, bio, i) 1146 + bio_for_each_segment_all(bvec, bio, i) 1147 1147 __free_page(bvec->bv_page); 1148 1148 1149 1149 bio_put(bio); ··· 1357 1357 /* 1358 1358 * make sure we dirty pages we wrote to 1359 1359 */ 1360 - __bio_for_each_segment(bvec, bio, i, 0) { 1360 + bio_for_each_segment_all(bvec, bio, i) { 1361 1361 if (bio_data_dir(bio) == READ) 1362 1362 set_page_dirty_lock(bvec->bv_page); 1363 1363 ··· 1463 1463 int i; 1464 1464 char *p = bmd->sgvecs[0].iov_base; 1465 1465 1466 - __bio_for_each_segment(bvec, bio, i, 0) { 1466 + bio_for_each_segment_all(bvec, bio, i) { 1467 1467 char *addr = page_address(bvec->bv_page); 1468 1468 int len = bmd->iovecs[i].bv_len; 1469 1469 ··· 1503 1503 if (!reading) { 1504 1504 void *p = data; 1505 1505 1506 - bio_for_each_segment(bvec, bio, i) { 1506 + bio_for_each_segment_all(bvec, bio, i) { 1507 1507 char *addr = page_address(bvec->bv_page); 1508 1508 1509 1509 memcpy(addr, p, bvec->bv_len); ··· 1789 1789 if (index >= bio->bi_idx) 1790 1790 index = bio->bi_vcnt - 1; 1791 1791 1792 - __bio_for_each_segment(bv, bio, i, 0) { 1792 + bio_for_each_segment_all(bv, bio, i) { 1793 1793 if (i == index) { 1794 1794 if (offset > bv->bv_offset) 1795 1795 sectors += (offset - bv->bv_offset) / sector_sz;
+1 -1
fs/exofs/ore.c
··· 401 401 struct bio_vec *bv; 402 402 unsigned i; 403 403 404 - __bio_for_each_segment(bv, bio, i, 0) { 404 + bio_for_each_segment_all(bv, bio, i) { 405 405 unsigned this_count = bv->bv_len; 406 406 407 407 if (likely(PAGE_SIZE == this_count))
+1 -1
fs/exofs/ore_raid.c
··· 432 432 if (!bio) 433 433 continue; 434 434 435 - __bio_for_each_segment(bv, bio, i, 0) { 435 + bio_for_each_segment_all(bv, bio, i) { 436 436 struct page *page = bv->bv_page; 437 437 438 438 SetPageUptodate(page);
+14 -3
include/linux/bio.h
··· 137 137 #define bio_io_error(bio) bio_endio((bio), -EIO) 138 138 139 139 /* 140 - * drivers should not use the __ version unless they _really_ want to 141 - * run through the entire bio and not just pending pieces 140 + * drivers should not use the __ version unless they _really_ know what 141 + * they're doing 142 142 */ 143 143 #define __bio_for_each_segment(bvl, bio, i, start_idx) \ 144 144 for (bvl = bio_iovec_idx((bio), (start_idx)), i = (start_idx); \ 145 145 i < (bio)->bi_vcnt; \ 146 146 bvl++, i++) 147 147 148 + /* 149 + * drivers should _never_ use the all version - the bio may have been split 150 + * before it got to the driver and the driver won't own all of it 151 + */ 152 + #define bio_for_each_segment_all(bvl, bio, i) \ 153 + for (i = 0; \ 154 + bvl = bio_iovec_idx((bio), (i)), i < (bio)->bi_vcnt; \ 155 + i++) 156 + 148 157 #define bio_for_each_segment(bvl, bio, i) \ 149 - __bio_for_each_segment(bvl, bio, i, (bio)->bi_idx) 158 + for (i = (bio)->bi_idx; \ 159 + bvl = bio_iovec_idx((bio), (i)), i < (bio)->bi_vcnt; \ 160 + i++) 150 161 151 162 /* 152 163 * get a reference to a bio, so it won't disappear. the intended use is
+1 -1
mm/bounce.c
··· 134 134 /* 135 135 * free up bounce indirect pages used 136 136 */ 137 - __bio_for_each_segment(bvec, bio, i, 0) { 137 + bio_for_each_segment_all(bvec, bio, i) { 138 138 org_vec = bio_orig->bi_io_vec + i; 139 139 if (bvec->bv_page == org_vec->bv_page) 140 140 continue;