| .. | .. |
|---|
| 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) |
|---|