.. | .. |
---|
18 | 18 | #include <linux/init.h> |
---|
19 | 19 | #include <linux/hash.h> |
---|
20 | 20 | #include <linux/highmem.h> |
---|
21 | | -#include <linux/bootmem.h> |
---|
| 21 | +#include <linux/memblock.h> |
---|
22 | 22 | #include <linux/printk.h> |
---|
23 | 23 | #include <asm/tlbflush.h> |
---|
24 | 24 | |
---|
.. | .. |
---|
163 | 163 | { |
---|
164 | 164 | struct bio *bio_orig = bio->bi_private; |
---|
165 | 165 | struct bio_vec *bvec, orig_vec; |
---|
166 | | - int i; |
---|
167 | 166 | struct bvec_iter orig_iter = bio_orig->bi_iter; |
---|
| 167 | + struct bvec_iter_all iter_all; |
---|
168 | 168 | |
---|
169 | 169 | /* |
---|
170 | 170 | * free up bounce indirect pages used |
---|
171 | 171 | */ |
---|
172 | | - bio_for_each_segment_all(bvec, bio, i) { |
---|
| 172 | + bio_for_each_segment_all(bvec, bio, iter_all) { |
---|
173 | 173 | orig_vec = bio_iter_iovec(bio_orig, orig_iter); |
---|
174 | 174 | if (bvec->bv_page != orig_vec.bv_page) { |
---|
175 | 175 | dec_zone_page_state(bvec->bv_page, NR_BOUNCE); |
---|
.. | .. |
---|
267 | 267 | break; |
---|
268 | 268 | } |
---|
269 | 269 | |
---|
270 | | - bio_crypt_clone(bio, bio_src, gfp_mask); |
---|
| 270 | + if (bio_crypt_clone(bio, bio_src, gfp_mask) < 0) |
---|
| 271 | + goto err_put; |
---|
271 | 272 | |
---|
272 | 273 | if (bio_integrity(bio_src) && |
---|
273 | | - bio_integrity_clone(bio, bio_src, gfp_mask) < 0) { |
---|
274 | | - bio_put(bio); |
---|
275 | | - return NULL; |
---|
276 | | - } |
---|
| 274 | + bio_integrity_clone(bio, bio_src, gfp_mask) < 0) |
---|
| 275 | + goto err_put; |
---|
277 | 276 | |
---|
278 | | - bio_clone_blkcg_association(bio, bio_src); |
---|
| 277 | + bio_clone_blkg_association(bio, bio_src); |
---|
| 278 | + blkcg_bio_issue_init(bio); |
---|
279 | 279 | |
---|
280 | 280 | return bio; |
---|
| 281 | + |
---|
| 282 | +err_put: |
---|
| 283 | + bio_put(bio); |
---|
| 284 | + return NULL; |
---|
281 | 285 | } |
---|
282 | 286 | |
---|
283 | 287 | static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig, |
---|
.. | .. |
---|
304 | 308 | if (!passthrough && sectors < bio_sectors(*bio_orig)) { |
---|
305 | 309 | bio = bio_split(*bio_orig, sectors, GFP_NOIO, &bounce_bio_split); |
---|
306 | 310 | bio_chain(bio, *bio_orig); |
---|
307 | | - generic_make_request(*bio_orig); |
---|
| 311 | + submit_bio_noacct(*bio_orig); |
---|
308 | 312 | *bio_orig = bio; |
---|
309 | 313 | } |
---|
310 | 314 | bio = bounce_clone_bio(*bio_orig, GFP_NOIO, passthrough ? NULL : |
---|
311 | 315 | &bounce_bio_set); |
---|
312 | 316 | |
---|
313 | | - bio_for_each_segment_all(to, bio, i) { |
---|
| 317 | + /* |
---|
| 318 | + * Bvec table can't be updated by bio_for_each_segment_all(), |
---|
| 319 | + * so retrieve bvec from the table directly. This way is safe |
---|
| 320 | + * because the 'bio' is single-page bvec. |
---|
| 321 | + */ |
---|
| 322 | + for (i = 0, to = bio->bi_io_vec; i < bio->bi_vcnt; to++, i++) { |
---|
314 | 323 | struct page *page = to->bv_page; |
---|
315 | 324 | |
---|
316 | 325 | if (page_to_pfn(page) <= q->limits.bounce_pfn) |
---|