diff options
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r-- | drivers/md/raid10.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index de5ed6fd8806..1c2eb38f3c51 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -659,7 +659,11 @@ static int raid10_mergeable_bvec(struct request_queue *q, | |||
659 | max = biovec->bv_len; | 659 | max = biovec->bv_len; |
660 | 660 | ||
661 | if (mddev->merge_check_needed) { | 661 | if (mddev->merge_check_needed) { |
662 | struct r10bio r10_bio; | 662 | struct { |
663 | struct r10bio r10_bio; | ||
664 | struct r10dev devs[conf->copies]; | ||
665 | } on_stack; | ||
666 | struct r10bio *r10_bio = &on_stack.r10_bio; | ||
663 | int s; | 667 | int s; |
664 | if (conf->reshape_progress != MaxSector) { | 668 | if (conf->reshape_progress != MaxSector) { |
665 | /* Cannot give any guidance during reshape */ | 669 | /* Cannot give any guidance during reshape */ |
@@ -667,18 +671,18 @@ static int raid10_mergeable_bvec(struct request_queue *q, | |||
667 | return biovec->bv_len; | 671 | return biovec->bv_len; |
668 | return 0; | 672 | return 0; |
669 | } | 673 | } |
670 | r10_bio.sector = sector; | 674 | r10_bio->sector = sector; |
671 | raid10_find_phys(conf, &r10_bio); | 675 | raid10_find_phys(conf, r10_bio); |
672 | rcu_read_lock(); | 676 | rcu_read_lock(); |
673 | for (s = 0; s < conf->copies; s++) { | 677 | for (s = 0; s < conf->copies; s++) { |
674 | int disk = r10_bio.devs[s].devnum; | 678 | int disk = r10_bio->devs[s].devnum; |
675 | struct md_rdev *rdev = rcu_dereference( | 679 | struct md_rdev *rdev = rcu_dereference( |
676 | conf->mirrors[disk].rdev); | 680 | conf->mirrors[disk].rdev); |
677 | if (rdev && !test_bit(Faulty, &rdev->flags)) { | 681 | if (rdev && !test_bit(Faulty, &rdev->flags)) { |
678 | struct request_queue *q = | 682 | struct request_queue *q = |
679 | bdev_get_queue(rdev->bdev); | 683 | bdev_get_queue(rdev->bdev); |
680 | if (q->merge_bvec_fn) { | 684 | if (q->merge_bvec_fn) { |
681 | bvm->bi_sector = r10_bio.devs[s].addr | 685 | bvm->bi_sector = r10_bio->devs[s].addr |
682 | + rdev->data_offset; | 686 | + rdev->data_offset; |
683 | bvm->bi_bdev = rdev->bdev; | 687 | bvm->bi_bdev = rdev->bdev; |
684 | max = min(max, q->merge_bvec_fn( | 688 | max = min(max, q->merge_bvec_fn( |
@@ -690,7 +694,7 @@ static int raid10_mergeable_bvec(struct request_queue *q, | |||
690 | struct request_queue *q = | 694 | struct request_queue *q = |
691 | bdev_get_queue(rdev->bdev); | 695 | bdev_get_queue(rdev->bdev); |
692 | if (q->merge_bvec_fn) { | 696 | if (q->merge_bvec_fn) { |
693 | bvm->bi_sector = r10_bio.devs[s].addr | 697 | bvm->bi_sector = r10_bio->devs[s].addr |
694 | + rdev->data_offset; | 698 | + rdev->data_offset; |
695 | bvm->bi_bdev = rdev->bdev; | 699 | bvm->bi_bdev = rdev->bdev; |
696 | max = min(max, q->merge_bvec_fn( | 700 | max = min(max, q->merge_bvec_fn( |
@@ -4414,14 +4418,18 @@ static int handle_reshape_read_error(struct mddev *mddev, | |||
4414 | { | 4418 | { |
4415 | /* Use sync reads to get the blocks from somewhere else */ | 4419 | /* Use sync reads to get the blocks from somewhere else */ |
4416 | int sectors = r10_bio->sectors; | 4420 | int sectors = r10_bio->sectors; |
4417 | struct r10bio r10b; | ||
4418 | struct r10conf *conf = mddev->private; | 4421 | struct r10conf *conf = mddev->private; |
4422 | struct { | ||
4423 | struct r10bio r10_bio; | ||
4424 | struct r10dev devs[conf->copies]; | ||
4425 | } on_stack; | ||
4426 | struct r10bio *r10b = &on_stack.r10_bio; | ||
4419 | int slot = 0; | 4427 | int slot = 0; |
4420 | int idx = 0; | 4428 | int idx = 0; |
4421 | struct bio_vec *bvec = r10_bio->master_bio->bi_io_vec; | 4429 | struct bio_vec *bvec = r10_bio->master_bio->bi_io_vec; |
4422 | 4430 | ||
4423 | r10b.sector = r10_bio->sector; | 4431 | r10b->sector = r10_bio->sector; |
4424 | __raid10_find_phys(&conf->prev, &r10b); | 4432 | __raid10_find_phys(&conf->prev, r10b); |
4425 | 4433 | ||
4426 | while (sectors) { | 4434 | while (sectors) { |
4427 | int s = sectors; | 4435 | int s = sectors; |
@@ -4432,7 +4440,7 @@ static int handle_reshape_read_error(struct mddev *mddev, | |||
4432 | s = PAGE_SIZE >> 9; | 4440 | s = PAGE_SIZE >> 9; |
4433 | 4441 | ||
4434 | while (!success) { | 4442 | while (!success) { |
4435 | int d = r10b.devs[slot].devnum; | 4443 | int d = r10b->devs[slot].devnum; |
4436 | struct md_rdev *rdev = conf->mirrors[d].rdev; | 4444 | struct md_rdev *rdev = conf->mirrors[d].rdev; |
4437 | sector_t addr; | 4445 | sector_t addr; |
4438 | if (rdev == NULL || | 4446 | if (rdev == NULL || |
@@ -4440,7 +4448,7 @@ static int handle_reshape_read_error(struct mddev *mddev, | |||
4440 | !test_bit(In_sync, &rdev->flags)) | 4448 | !test_bit(In_sync, &rdev->flags)) |
4441 | goto failed; | 4449 | goto failed; |
4442 | 4450 | ||
4443 | addr = r10b.devs[slot].addr + idx * PAGE_SIZE; | 4451 | addr = r10b->devs[slot].addr + idx * PAGE_SIZE; |
4444 | success = sync_page_io(rdev, | 4452 | success = sync_page_io(rdev, |
4445 | addr, | 4453 | addr, |
4446 | s << 9, | 4454 | s << 9, |