aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/bio.h20
-rw-r--r--include/linux/bvec.h14
2 files changed, 22 insertions, 12 deletions
diff --git a/include/linux/bio.h b/include/linux/bio.h
index bb6090aa165d..e584673c1881 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -120,19 +120,23 @@ static inline bool bio_full(struct bio *bio)
120 return bio->bi_vcnt >= bio->bi_max_vecs; 120 return bio->bi_vcnt >= bio->bi_max_vecs;
121} 121}
122 122
123#define mp_bvec_for_each_segment(bv, bvl, i, iter_all) \ 123static inline bool bio_next_segment(const struct bio *bio,
124 for (bv = bvec_init_iter_all(&iter_all); \ 124 struct bvec_iter_all *iter)
125 (iter_all.done < (bvl)->bv_len) && \ 125{
126 (mp_bvec_next_segment((bvl), &iter_all), 1); \ 126 if (iter->idx >= bio->bi_vcnt)
127 iter_all.done += bv->bv_len, i += 1) 127 return false;
128
129 bvec_advance(&bio->bi_io_vec[iter->idx], iter);
130 return true;
131}
128 132
129/* 133/*
130 * drivers should _never_ use the all version - the bio may have been split 134 * drivers should _never_ use the all version - the bio may have been split
131 * before it got to the driver and the driver won't own all of it 135 * before it got to the driver and the driver won't own all of it
132 */ 136 */
133#define bio_for_each_segment_all(bvl, bio, i, iter_all) \ 137#define bio_for_each_segment_all(bvl, bio, i, iter) \
134 for (i = 0, iter_all.idx = 0; iter_all.idx < (bio)->bi_vcnt; iter_all.idx++) \ 138 for (i = 0, bvl = bvec_init_iter_all(&iter); \
135 mp_bvec_for_each_segment(bvl, &((bio)->bi_io_vec[iter_all.idx]), i, iter_all) 139 bio_next_segment((bio), &iter); i++)
136 140
137static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter, 141static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
138 unsigned bytes) 142 unsigned bytes)
diff --git a/include/linux/bvec.h b/include/linux/bvec.h
index f6275c4da13a..3bc91879e1e2 100644
--- a/include/linux/bvec.h
+++ b/include/linux/bvec.h
@@ -145,18 +145,18 @@ static inline bool bvec_iter_advance(const struct bio_vec *bv,
145 145
146static inline struct bio_vec *bvec_init_iter_all(struct bvec_iter_all *iter_all) 146static inline struct bio_vec *bvec_init_iter_all(struct bvec_iter_all *iter_all)
147{ 147{
148 iter_all->bv.bv_page = NULL;
149 iter_all->done = 0; 148 iter_all->done = 0;
149 iter_all->idx = 0;
150 150
151 return &iter_all->bv; 151 return &iter_all->bv;
152} 152}
153 153
154static inline void mp_bvec_next_segment(const struct bio_vec *bvec, 154static inline void bvec_advance(const struct bio_vec *bvec,
155 struct bvec_iter_all *iter_all) 155 struct bvec_iter_all *iter_all)
156{ 156{
157 struct bio_vec *bv = &iter_all->bv; 157 struct bio_vec *bv = &iter_all->bv;
158 158
159 if (bv->bv_page) { 159 if (iter_all->done) {
160 bv->bv_page = nth_page(bv->bv_page, 1); 160 bv->bv_page = nth_page(bv->bv_page, 1);
161 bv->bv_offset = 0; 161 bv->bv_offset = 0;
162 } else { 162 } else {
@@ -165,6 +165,12 @@ static inline void mp_bvec_next_segment(const struct bio_vec *bvec,
165 } 165 }
166 bv->bv_len = min_t(unsigned int, PAGE_SIZE - bv->bv_offset, 166 bv->bv_len = min_t(unsigned int, PAGE_SIZE - bv->bv_offset,
167 bvec->bv_len - iter_all->done); 167 bvec->bv_len - iter_all->done);
168 iter_all->done += bv->bv_len;
169
170 if (iter_all->done == bvec->bv_len) {
171 iter_all->idx++;
172 iter_all->done = 0;
173 }
168} 174}
169 175
170/* 176/*