Merge tag 'block-6.12-20241026' of git://git.kernel.dk/linux

Pull block fixes from Jens Axboe:

- Pull request for MD via Song fixing a few issues

- Fix a wrong check in blk_rq_map_user_bvec(), causing IO errors on
passthrough IO (Xinyu)

* tag 'block-6.12-20241026' of git://git.kernel.dk/linux:
block: fix sanity checks in blk_rq_map_user_bvec
md/raid10: fix null ptr dereference in raid10_size()
md: ensure child flush IO does not affect origin bio->bi_status

Changed files
+29 -6
block
drivers
+1 -3
block/blk-map.c
··· 600 600 if (nsegs >= nr_segs || bytes > UINT_MAX - bv->bv_len) 601 601 goto put_bio; 602 602 if (bytes + bv->bv_len > nr_iter) 603 - goto put_bio; 604 - if (bv->bv_offset + bv->bv_len > PAGE_SIZE) 605 - goto put_bio; 603 + break; 606 604 607 605 nsegs++; 608 606 bytes += bv->bv_len;
+23 -1
drivers/md/md.c
··· 546 546 return 0; 547 547 } 548 548 549 + /* 550 + * The only difference from bio_chain_endio() is that the current 551 + * bi_status of bio does not affect the bi_status of parent. 552 + */ 553 + static void md_end_flush(struct bio *bio) 554 + { 555 + struct bio *parent = bio->bi_private; 556 + 557 + /* 558 + * If any flush io error before the power failure, 559 + * disk data may be lost. 560 + */ 561 + if (bio->bi_status) 562 + pr_err("md: %pg flush io error %d\n", bio->bi_bdev, 563 + blk_status_to_errno(bio->bi_status)); 564 + 565 + bio_put(bio); 566 + bio_endio(parent); 567 + } 568 + 549 569 bool md_flush_request(struct mddev *mddev, struct bio *bio) 550 570 { 551 571 struct md_rdev *rdev; ··· 585 565 new = bio_alloc_bioset(rdev->bdev, 0, 586 566 REQ_OP_WRITE | REQ_PREFLUSH, GFP_NOIO, 587 567 &mddev->bio_set); 588 - bio_chain(new, bio); 568 + new->bi_private = bio; 569 + new->bi_end_io = md_end_flush; 570 + bio_inc_remaining(bio); 589 571 submit_bio(new); 590 572 } 591 573
+5 -2
drivers/md/raid10.c
··· 4061 4061 } 4062 4062 4063 4063 if (!mddev_is_dm(conf->mddev)) { 4064 - ret = raid10_set_queue_limits(mddev); 4065 - if (ret) 4064 + int err = raid10_set_queue_limits(mddev); 4065 + 4066 + if (err) { 4067 + ret = err; 4066 4068 goto out_free_conf; 4069 + } 4067 4070 } 4068 4071 4069 4072 /* need to check that every block has at least one working mirror */