Commit d74c6d514fe314b8bdab58b487b25992291577ec

Authored by Kent Overstreet
1 parent 6bc454d150

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>

Showing 7 changed files with 25 additions and 14 deletions Side-by-side Diff

... ... @@ -952,7 +952,7 @@
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;
... ... @@ -1291,7 +1291,7 @@
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);
... ... @@ -961,7 +961,7 @@
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,7 +1143,7 @@
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,7 +1357,7 @@
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,7 +1463,7 @@
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,7 +1503,7 @@
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,7 +1789,7 @@
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;
... ... @@ -401,7 +401,7 @@
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))
... ... @@ -432,7 +432,7 @@
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);
... ... @@ -137,16 +137,27 @@
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
... ... @@ -134,7 +134,7 @@
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;