diff options
| -rw-r--r-- | drivers/md/md.c | 9 | ||||
| -rw-r--r-- | drivers/md/raid10.c | 30 | ||||
| -rw-r--r-- | drivers/md/raid10.h | 2 |
3 files changed, 26 insertions, 15 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index fcd098794d37..3f6203a4c7ea 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -1108,8 +1108,11 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor | |||
| 1108 | ret = 0; | 1108 | ret = 0; |
| 1109 | } | 1109 | } |
| 1110 | rdev->sectors = rdev->sb_start; | 1110 | rdev->sectors = rdev->sb_start; |
| 1111 | /* Limit to 4TB as metadata cannot record more than that */ | 1111 | /* Limit to 4TB as metadata cannot record more than that. |
| 1112 | if (rdev->sectors >= (2ULL << 32)) | 1112 | * (not needed for Linear and RAID0 as metadata doesn't |
| 1113 | * record this size) | ||
| 1114 | */ | ||
| 1115 | if (rdev->sectors >= (2ULL << 32) && sb->level >= 1) | ||
| 1113 | rdev->sectors = (2ULL << 32) - 2; | 1116 | rdev->sectors = (2ULL << 32) - 2; |
| 1114 | 1117 | ||
| 1115 | if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1) | 1118 | if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1) |
| @@ -1400,7 +1403,7 @@ super_90_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors) | |||
| 1400 | /* Limit to 4TB as metadata cannot record more than that. | 1403 | /* Limit to 4TB as metadata cannot record more than that. |
| 1401 | * 4TB == 2^32 KB, or 2*2^32 sectors. | 1404 | * 4TB == 2^32 KB, or 2*2^32 sectors. |
| 1402 | */ | 1405 | */ |
| 1403 | if (num_sectors >= (2ULL << 32)) | 1406 | if (num_sectors >= (2ULL << 32) && rdev->mddev->level >= 1) |
| 1404 | num_sectors = (2ULL << 32) - 2; | 1407 | num_sectors = (2ULL << 32) - 2; |
| 1405 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, | 1408 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, |
| 1406 | rdev->sb_page); | 1409 | rdev->sb_page); |
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, |
diff --git a/drivers/md/raid10.h b/drivers/md/raid10.h index 007c2c68dd83..1054cf602345 100644 --- a/drivers/md/raid10.h +++ b/drivers/md/raid10.h | |||
| @@ -110,7 +110,7 @@ struct r10bio { | |||
| 110 | * We choose the number when they are allocated. | 110 | * We choose the number when they are allocated. |
| 111 | * We sometimes need an extra bio to write to the replacement. | 111 | * We sometimes need an extra bio to write to the replacement. |
| 112 | */ | 112 | */ |
| 113 | struct { | 113 | struct r10dev { |
| 114 | struct bio *bio; | 114 | struct bio *bio; |
| 115 | union { | 115 | union { |
| 116 | struct bio *repl_bio; /* used for resync and | 116 | struct bio *repl_bio; /* used for resync and |
