aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid10.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r--drivers/md/raid10.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index de5ed6fd8806..0138a727c1f3 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(
@@ -1508,14 +1512,16 @@ static int _enough(struct r10conf *conf, struct geom *geo, int ignore)
1508 do { 1512 do {
1509 int n = conf->copies; 1513 int n = conf->copies;
1510 int cnt = 0; 1514 int cnt = 0;
1515 int this = first;
1511 while (n--) { 1516 while (n--) {
1512 if (conf->mirrors[first].rdev && 1517 if (conf->mirrors[this].rdev &&
1513 first != ignore) 1518 this != ignore)
1514 cnt++; 1519 cnt++;
1515 first = (first+1) % geo->raid_disks; 1520 this = (this+1) % geo->raid_disks;
1516 } 1521 }
1517 if (cnt == 0) 1522 if (cnt == 0)
1518 return 0; 1523 return 0;
1524 first = (first + geo->near_copies) % geo->raid_disks;
1519 } while (first != 0); 1525 } while (first != 0);
1520 return 1; 1526 return 1;
1521} 1527}
@@ -4414,14 +4420,18 @@ static int handle_reshape_read_error(struct mddev *mddev,
4414{ 4420{
4415 /* Use sync reads to get the blocks from somewhere else */ 4421 /* Use sync reads to get the blocks from somewhere else */
4416 int sectors = r10_bio->sectors; 4422 int sectors = r10_bio->sectors;
4417 struct r10bio r10b;
4418 struct r10conf *conf = mddev->private; 4423 struct r10conf *conf = mddev->private;
4424 struct {
4425 struct r10bio r10_bio;
4426 struct r10dev devs[conf->copies];
4427 } on_stack;
4428 struct r10bio *r10b = &on_stack.r10_bio;
4419 int slot = 0; 4429 int slot = 0;
4420 int idx = 0; 4430 int idx = 0;
4421 struct bio_vec *bvec = r10_bio->master_bio->bi_io_vec; 4431 struct bio_vec *bvec = r10_bio->master_bio->bi_io_vec;
4422 4432
4423 r10b.sector = r10_bio->sector; 4433 r10b->sector = r10_bio->sector;
4424 __raid10_find_phys(&conf->prev, &r10b); 4434 __raid10_find_phys(&conf->prev, r10b);
4425 4435
4426 while (sectors) { 4436 while (sectors) {
4427 int s = sectors; 4437 int s = sectors;
@@ -4432,7 +4442,7 @@ static int handle_reshape_read_error(struct mddev *mddev,
4432 s = PAGE_SIZE >> 9; 4442 s = PAGE_SIZE >> 9;
4433 4443
4434 while (!success) { 4444 while (!success) {
4435 int d = r10b.devs[slot].devnum; 4445 int d = r10b->devs[slot].devnum;
4436 struct md_rdev *rdev = conf->mirrors[d].rdev; 4446 struct md_rdev *rdev = conf->mirrors[d].rdev;
4437 sector_t addr; 4447 sector_t addr;
4438 if (rdev == NULL || 4448 if (rdev == NULL ||
@@ -4440,7 +4450,7 @@ static int handle_reshape_read_error(struct mddev *mddev,
4440 !test_bit(In_sync, &rdev->flags)) 4450 !test_bit(In_sync, &rdev->flags))
4441 goto failed; 4451 goto failed;
4442 4452
4443 addr = r10b.devs[slot].addr + idx * PAGE_SIZE; 4453 addr = r10b->devs[slot].addr + idx * PAGE_SIZE;
4444 success = sync_page_io(rdev, 4454 success = sync_page_io(rdev,
4445 addr, 4455 addr,
4446 s << 9, 4456 s << 9,