[PATCH v2 21/26] block: Convert some code to bio_for_each_segment_all()
A few places in the code were either open coding or using the wrong version - fix. Signed-off-by: Kent Overstreet CC: Jens Axboe CC: NeilBrown --- drivers/md/dm-crypt.c | 3 +-- drivers/md/raid1.c| 10 +++--- fs/bio.c | 20 ++-- fs/direct-io.c| 8 4 files changed, 18 insertions(+), 23 deletions(-) diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index bbf459b..f50798e 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -858,8 +858,7 @@ static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone) unsigned int i; struct bio_vec *bv; - for (i = 0; i < clone->bi_vcnt; i++) { - bv = bio_iovec_idx(clone, i); + bio_for_each_segment_all(bv, clone, i) { BUG_ON(!bv->bv_page); mempool_free(bv->bv_page, cc->page_pool); bv->bv_page = NULL; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index ade95ac..d30b4cb 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -921,7 +921,7 @@ static void alloc_behind_pages(struct bio *bio, struct r1bio *r1_bio) if (unlikely(!bvecs)) return; - bio_for_each_segment(bvec, bio, i) { + bio_for_each_segment_all(bvec, bio, i) { bvecs[i] = *bvec; bvecs[i].bv_page = alloc_page(GFP_NOIO); if (unlikely(!bvecs[i].bv_page)) @@ -1276,12 +1276,8 @@ read_again: struct bio_vec *bvec; int j; - /* Yes, I really want the '__' version so that -* we clear any unused pointer in the io_vec, rather -* than leave them unchanged. This is important -* because when we come to free the pages, we won't -* know the original bi_idx, so we just free -* them all + /* +* We trimmed the bio, so _all is legit */ bio_for_each_segment_all(bvec, mbio, j) bvec->bv_page = r1_bio->behind_bvecs[j].bv_page; diff --git a/fs/bio.c b/fs/bio.c index efdc437..d88ad77 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -1546,11 +1546,11 @@ EXPORT_SYMBOL(bio_copy_kern); */ void bio_set_pages_dirty(struct bio *bio) { - struct bio_vec *bvec = bio->bi_io_vec; + struct bio_vec *bvec; int i; - for (i = 0; i < bio->bi_vcnt; i++) { - struct page *page = bvec[i].bv_page; + bio_for_each_segment_all(bvec, bio, i) { + struct page *page = bvec->bv_page; if (page && !PageCompound(page)) set_page_dirty_lock(page); @@ -1559,11 +1559,11 @@ void bio_set_pages_dirty(struct bio *bio) static void bio_release_pages(struct bio *bio) { - struct bio_vec *bvec = bio->bi_io_vec; + struct bio_vec *bvec; int i; - for (i = 0; i < bio->bi_vcnt; i++) { - struct page *page = bvec[i].bv_page; + bio_for_each_segment_all(bvec, bio, i) { + struct page *page = bvec->bv_page; if (page) put_page(page); @@ -1612,16 +1612,16 @@ static void bio_dirty_fn(struct work_struct *work) void bio_check_pages_dirty(struct bio *bio) { - struct bio_vec *bvec = bio->bi_io_vec; + struct bio_vec *bvec; int nr_clean_pages = 0; int i; - for (i = 0; i < bio->bi_vcnt; i++) { - struct page *page = bvec[i].bv_page; + bio_for_each_segment_all(bvec, bio, i) { + struct page *page = bvec->bv_page; if (PageDirty(page) || PageCompound(page)) { page_cache_release(page); - bvec[i].bv_page = NULL; + bvec->bv_page = NULL; } else { nr_clean_pages++; } diff --git a/fs/direct-io.c b/fs/direct-io.c index f86c720..6089916 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -441,8 +441,8 @@ static struct bio *dio_await_one(struct dio *dio) static int dio_bio_complete(struct dio *dio, struct bio *bio) { const int uptodate = test_bit(BIO_UPTODATE, >bi_flags); - struct bio_vec *bvec = bio->bi_io_vec; - int page_no; + struct bio_vec *bvec; + unsigned i; if (!uptodate) dio->io_error = -EIO; @@ -450,8 +450,8 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio) if (dio->is_async && dio->rw == READ) { bio_check_pages_dirty(bio); /* transfers ownership */ } else { - for (page_no = 0; page_no < bio->bi_vcnt; page_no++) { - struct page *page = bvec[page_no].bv_page; + bio_for_each_segment_all(bvec, bio, i) { + struct page *page
[PATCH v2 21/26] block: Convert some code to bio_for_each_segment_all()
A few places in the code were either open coding or using the wrong version - fix. Signed-off-by: Kent Overstreet koverstr...@google.com CC: Jens Axboe ax...@kernel.dk CC: NeilBrown ne...@suse.de --- drivers/md/dm-crypt.c | 3 +-- drivers/md/raid1.c| 10 +++--- fs/bio.c | 20 ++-- fs/direct-io.c| 8 4 files changed, 18 insertions(+), 23 deletions(-) diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index bbf459b..f50798e 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -858,8 +858,7 @@ static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone) unsigned int i; struct bio_vec *bv; - for (i = 0; i clone-bi_vcnt; i++) { - bv = bio_iovec_idx(clone, i); + bio_for_each_segment_all(bv, clone, i) { BUG_ON(!bv-bv_page); mempool_free(bv-bv_page, cc-page_pool); bv-bv_page = NULL; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index ade95ac..d30b4cb 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -921,7 +921,7 @@ static void alloc_behind_pages(struct bio *bio, struct r1bio *r1_bio) if (unlikely(!bvecs)) return; - bio_for_each_segment(bvec, bio, i) { + bio_for_each_segment_all(bvec, bio, i) { bvecs[i] = *bvec; bvecs[i].bv_page = alloc_page(GFP_NOIO); if (unlikely(!bvecs[i].bv_page)) @@ -1276,12 +1276,8 @@ read_again: struct bio_vec *bvec; int j; - /* Yes, I really want the '__' version so that -* we clear any unused pointer in the io_vec, rather -* than leave them unchanged. This is important -* because when we come to free the pages, we won't -* know the original bi_idx, so we just free -* them all + /* +* We trimmed the bio, so _all is legit */ bio_for_each_segment_all(bvec, mbio, j) bvec-bv_page = r1_bio-behind_bvecs[j].bv_page; diff --git a/fs/bio.c b/fs/bio.c index efdc437..d88ad77 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -1546,11 +1546,11 @@ EXPORT_SYMBOL(bio_copy_kern); */ void bio_set_pages_dirty(struct bio *bio) { - struct bio_vec *bvec = bio-bi_io_vec; + struct bio_vec *bvec; int i; - for (i = 0; i bio-bi_vcnt; i++) { - struct page *page = bvec[i].bv_page; + bio_for_each_segment_all(bvec, bio, i) { + struct page *page = bvec-bv_page; if (page !PageCompound(page)) set_page_dirty_lock(page); @@ -1559,11 +1559,11 @@ void bio_set_pages_dirty(struct bio *bio) static void bio_release_pages(struct bio *bio) { - struct bio_vec *bvec = bio-bi_io_vec; + struct bio_vec *bvec; int i; - for (i = 0; i bio-bi_vcnt; i++) { - struct page *page = bvec[i].bv_page; + bio_for_each_segment_all(bvec, bio, i) { + struct page *page = bvec-bv_page; if (page) put_page(page); @@ -1612,16 +1612,16 @@ static void bio_dirty_fn(struct work_struct *work) void bio_check_pages_dirty(struct bio *bio) { - struct bio_vec *bvec = bio-bi_io_vec; + struct bio_vec *bvec; int nr_clean_pages = 0; int i; - for (i = 0; i bio-bi_vcnt; i++) { - struct page *page = bvec[i].bv_page; + bio_for_each_segment_all(bvec, bio, i) { + struct page *page = bvec-bv_page; if (PageDirty(page) || PageCompound(page)) { page_cache_release(page); - bvec[i].bv_page = NULL; + bvec-bv_page = NULL; } else { nr_clean_pages++; } diff --git a/fs/direct-io.c b/fs/direct-io.c index f86c720..6089916 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -441,8 +441,8 @@ static struct bio *dio_await_one(struct dio *dio) static int dio_bio_complete(struct dio *dio, struct bio *bio) { const int uptodate = test_bit(BIO_UPTODATE, bio-bi_flags); - struct bio_vec *bvec = bio-bi_io_vec; - int page_no; + struct bio_vec *bvec; + unsigned i; if (!uptodate) dio-io_error = -EIO; @@ -450,8 +450,8 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio) if (dio-is_async dio-rw == READ) { bio_check_pages_dirty(bio); /* transfers ownership */ } else { - for (page_no = 0; page_no bio-bi_vcnt; page_no++) { - struct page *page = bvec[page_no].bv_page; + bio_for_each_segment_all(bvec, bio, i) { +
Re: [PATCH v2 21/26] block: Convert some code to bio_for_each_segment_all()
On Thu, Sep 20, 2012 at 05:38:32PM -0700, Tejun Heo wrote: > On Mon, Sep 10, 2012 at 05:22:32PM -0700, Kent Overstreet wrote: > > A few places in the code were either open coding or using the wrong > > version - fix. > > > > Signed-off-by: Kent Overstreet > > CC: Jens Axboe > > CC: NeilBrown > > --- > > --- a/drivers/md/raid1.c > > +++ b/drivers/md/raid1.c > > @@ -921,7 +921,7 @@ static void alloc_behind_pages(struct bio *bio, struct > > r1bio *r1_bio) > > if (unlikely(!bvecs)) > > return; > > > > - bio_for_each_segment(bvec, bio, i) { > > + bio_for_each_segment_all(bvec, bio, i) { > > I don't get this conversion. Why is this necessary? Not necessary, just a consistency thing - this bio is a clone that md owns (and the clone was trimmed, so we know bi_idx is 0). Also, it wasn't an issue here but after the patch that introduces the bvec iter it's no longer possible to modify the biovec through bio_for_each_segment_all() - it doesn't increment a pointer to the current bvec, you pass in a struct bio_vec (not a pointer) which is updated with what the current biovec would be (taking into account bi_bvec_done and bi_size). So because of that it is IMO more worthwhile to be consistent about bio_for_each_segment()/bio_for_each_segment_all() usage. Suppose I should stick all that in the patch description. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 21/26] block: Convert some code to bio_for_each_segment_all()
On Mon, Sep 10, 2012 at 05:22:32PM -0700, Kent Overstreet wrote: > A few places in the code were either open coding or using the wrong > version - fix. > > Signed-off-by: Kent Overstreet > CC: Jens Axboe > CC: NeilBrown > --- > --- a/drivers/md/raid1.c > +++ b/drivers/md/raid1.c > @@ -921,7 +921,7 @@ static void alloc_behind_pages(struct bio *bio, struct > r1bio *r1_bio) > if (unlikely(!bvecs)) > return; > > - bio_for_each_segment(bvec, bio, i) { > + bio_for_each_segment_all(bvec, bio, i) { I don't get this conversion. Why is this necessary? -- tejun -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 21/26] block: Convert some code to bio_for_each_segment_all()
On Mon, Sep 10, 2012 at 05:22:32PM -0700, Kent Overstreet wrote: A few places in the code were either open coding or using the wrong version - fix. Signed-off-by: Kent Overstreet koverstr...@google.com CC: Jens Axboe ax...@kernel.dk CC: NeilBrown ne...@suse.de --- --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -921,7 +921,7 @@ static void alloc_behind_pages(struct bio *bio, struct r1bio *r1_bio) if (unlikely(!bvecs)) return; - bio_for_each_segment(bvec, bio, i) { + bio_for_each_segment_all(bvec, bio, i) { I don't get this conversion. Why is this necessary? -- tejun -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 21/26] block: Convert some code to bio_for_each_segment_all()
On Thu, Sep 20, 2012 at 05:38:32PM -0700, Tejun Heo wrote: On Mon, Sep 10, 2012 at 05:22:32PM -0700, Kent Overstreet wrote: A few places in the code were either open coding or using the wrong version - fix. Signed-off-by: Kent Overstreet koverstr...@google.com CC: Jens Axboe ax...@kernel.dk CC: NeilBrown ne...@suse.de --- --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -921,7 +921,7 @@ static void alloc_behind_pages(struct bio *bio, struct r1bio *r1_bio) if (unlikely(!bvecs)) return; - bio_for_each_segment(bvec, bio, i) { + bio_for_each_segment_all(bvec, bio, i) { I don't get this conversion. Why is this necessary? Not necessary, just a consistency thing - this bio is a clone that md owns (and the clone was trimmed, so we know bi_idx is 0). Also, it wasn't an issue here but after the patch that introduces the bvec iter it's no longer possible to modify the biovec through bio_for_each_segment_all() - it doesn't increment a pointer to the current bvec, you pass in a struct bio_vec (not a pointer) which is updated with what the current biovec would be (taking into account bi_bvec_done and bi_size). So because of that it is IMO more worthwhile to be consistent about bio_for_each_segment()/bio_for_each_segment_all() usage. Suppose I should stick all that in the patch description. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 21/26] block: Convert some code to bio_for_each_segment_all()
A few places in the code were either open coding or using the wrong version - fix. Signed-off-by: Kent Overstreet CC: Jens Axboe CC: NeilBrown --- drivers/md/dm-crypt.c | 3 +-- drivers/md/raid1.c| 10 +++--- fs/bio.c | 20 ++-- fs/direct-io.c| 8 4 files changed, 18 insertions(+), 23 deletions(-) diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index bbf459b..f50798e 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -858,8 +858,7 @@ static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone) unsigned int i; struct bio_vec *bv; - for (i = 0; i < clone->bi_vcnt; i++) { - bv = bio_iovec_idx(clone, i); + bio_for_each_segment_all(bv, clone, i) { BUG_ON(!bv->bv_page); mempool_free(bv->bv_page, cc->page_pool); bv->bv_page = NULL; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index ade95ac..d30b4cb 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -921,7 +921,7 @@ static void alloc_behind_pages(struct bio *bio, struct r1bio *r1_bio) if (unlikely(!bvecs)) return; - bio_for_each_segment(bvec, bio, i) { + bio_for_each_segment_all(bvec, bio, i) { bvecs[i] = *bvec; bvecs[i].bv_page = alloc_page(GFP_NOIO); if (unlikely(!bvecs[i].bv_page)) @@ -1276,12 +1276,8 @@ read_again: struct bio_vec *bvec; int j; - /* Yes, I really want the '__' version so that -* we clear any unused pointer in the io_vec, rather -* than leave them unchanged. This is important -* because when we come to free the pages, we won't -* know the original bi_idx, so we just free -* them all + /* +* We trimmed the bio, so _all is legit */ bio_for_each_segment_all(bvec, mbio, j) bvec->bv_page = r1_bio->behind_bvecs[j].bv_page; diff --git a/fs/bio.c b/fs/bio.c index efdc437..d88ad77 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -1546,11 +1546,11 @@ EXPORT_SYMBOL(bio_copy_kern); */ void bio_set_pages_dirty(struct bio *bio) { - struct bio_vec *bvec = bio->bi_io_vec; + struct bio_vec *bvec; int i; - for (i = 0; i < bio->bi_vcnt; i++) { - struct page *page = bvec[i].bv_page; + bio_for_each_segment_all(bvec, bio, i) { + struct page *page = bvec->bv_page; if (page && !PageCompound(page)) set_page_dirty_lock(page); @@ -1559,11 +1559,11 @@ void bio_set_pages_dirty(struct bio *bio) static void bio_release_pages(struct bio *bio) { - struct bio_vec *bvec = bio->bi_io_vec; + struct bio_vec *bvec; int i; - for (i = 0; i < bio->bi_vcnt; i++) { - struct page *page = bvec[i].bv_page; + bio_for_each_segment_all(bvec, bio, i) { + struct page *page = bvec->bv_page; if (page) put_page(page); @@ -1612,16 +1612,16 @@ static void bio_dirty_fn(struct work_struct *work) void bio_check_pages_dirty(struct bio *bio) { - struct bio_vec *bvec = bio->bi_io_vec; + struct bio_vec *bvec; int nr_clean_pages = 0; int i; - for (i = 0; i < bio->bi_vcnt; i++) { - struct page *page = bvec[i].bv_page; + bio_for_each_segment_all(bvec, bio, i) { + struct page *page = bvec->bv_page; if (PageDirty(page) || PageCompound(page)) { page_cache_release(page); - bvec[i].bv_page = NULL; + bvec->bv_page = NULL; } else { nr_clean_pages++; } diff --git a/fs/direct-io.c b/fs/direct-io.c index f86c720..6089916 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -441,8 +441,8 @@ static struct bio *dio_await_one(struct dio *dio) static int dio_bio_complete(struct dio *dio, struct bio *bio) { const int uptodate = test_bit(BIO_UPTODATE, >bi_flags); - struct bio_vec *bvec = bio->bi_io_vec; - int page_no; + struct bio_vec *bvec; + unsigned i; if (!uptodate) dio->io_error = -EIO; @@ -450,8 +450,8 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio) if (dio->is_async && dio->rw == READ) { bio_check_pages_dirty(bio); /* transfers ownership */ } else { - for (page_no = 0; page_no < bio->bi_vcnt; page_no++) { - struct page *page = bvec[page_no].bv_page; + bio_for_each_segment_all(bvec, bio, i) { + struct page *page
[PATCH v2 21/26] block: Convert some code to bio_for_each_segment_all()
A few places in the code were either open coding or using the wrong version - fix. Signed-off-by: Kent Overstreet koverstr...@google.com CC: Jens Axboe ax...@kernel.dk CC: NeilBrown ne...@suse.de --- drivers/md/dm-crypt.c | 3 +-- drivers/md/raid1.c| 10 +++--- fs/bio.c | 20 ++-- fs/direct-io.c| 8 4 files changed, 18 insertions(+), 23 deletions(-) diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index bbf459b..f50798e 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -858,8 +858,7 @@ static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone) unsigned int i; struct bio_vec *bv; - for (i = 0; i clone-bi_vcnt; i++) { - bv = bio_iovec_idx(clone, i); + bio_for_each_segment_all(bv, clone, i) { BUG_ON(!bv-bv_page); mempool_free(bv-bv_page, cc-page_pool); bv-bv_page = NULL; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index ade95ac..d30b4cb 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -921,7 +921,7 @@ static void alloc_behind_pages(struct bio *bio, struct r1bio *r1_bio) if (unlikely(!bvecs)) return; - bio_for_each_segment(bvec, bio, i) { + bio_for_each_segment_all(bvec, bio, i) { bvecs[i] = *bvec; bvecs[i].bv_page = alloc_page(GFP_NOIO); if (unlikely(!bvecs[i].bv_page)) @@ -1276,12 +1276,8 @@ read_again: struct bio_vec *bvec; int j; - /* Yes, I really want the '__' version so that -* we clear any unused pointer in the io_vec, rather -* than leave them unchanged. This is important -* because when we come to free the pages, we won't -* know the original bi_idx, so we just free -* them all + /* +* We trimmed the bio, so _all is legit */ bio_for_each_segment_all(bvec, mbio, j) bvec-bv_page = r1_bio-behind_bvecs[j].bv_page; diff --git a/fs/bio.c b/fs/bio.c index efdc437..d88ad77 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -1546,11 +1546,11 @@ EXPORT_SYMBOL(bio_copy_kern); */ void bio_set_pages_dirty(struct bio *bio) { - struct bio_vec *bvec = bio-bi_io_vec; + struct bio_vec *bvec; int i; - for (i = 0; i bio-bi_vcnt; i++) { - struct page *page = bvec[i].bv_page; + bio_for_each_segment_all(bvec, bio, i) { + struct page *page = bvec-bv_page; if (page !PageCompound(page)) set_page_dirty_lock(page); @@ -1559,11 +1559,11 @@ void bio_set_pages_dirty(struct bio *bio) static void bio_release_pages(struct bio *bio) { - struct bio_vec *bvec = bio-bi_io_vec; + struct bio_vec *bvec; int i; - for (i = 0; i bio-bi_vcnt; i++) { - struct page *page = bvec[i].bv_page; + bio_for_each_segment_all(bvec, bio, i) { + struct page *page = bvec-bv_page; if (page) put_page(page); @@ -1612,16 +1612,16 @@ static void bio_dirty_fn(struct work_struct *work) void bio_check_pages_dirty(struct bio *bio) { - struct bio_vec *bvec = bio-bi_io_vec; + struct bio_vec *bvec; int nr_clean_pages = 0; int i; - for (i = 0; i bio-bi_vcnt; i++) { - struct page *page = bvec[i].bv_page; + bio_for_each_segment_all(bvec, bio, i) { + struct page *page = bvec-bv_page; if (PageDirty(page) || PageCompound(page)) { page_cache_release(page); - bvec[i].bv_page = NULL; + bvec-bv_page = NULL; } else { nr_clean_pages++; } diff --git a/fs/direct-io.c b/fs/direct-io.c index f86c720..6089916 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -441,8 +441,8 @@ static struct bio *dio_await_one(struct dio *dio) static int dio_bio_complete(struct dio *dio, struct bio *bio) { const int uptodate = test_bit(BIO_UPTODATE, bio-bi_flags); - struct bio_vec *bvec = bio-bi_io_vec; - int page_no; + struct bio_vec *bvec; + unsigned i; if (!uptodate) dio-io_error = -EIO; @@ -450,8 +450,8 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio) if (dio-is_async dio-rw == READ) { bio_check_pages_dirty(bio); /* transfers ownership */ } else { - for (page_no = 0; page_no bio-bi_vcnt; page_no++) { - struct page *page = bvec[page_no].bv_page; + bio_for_each_segment_all(bvec, bio, i) { +