diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/raid10.c | 110 |
1 files changed, 80 insertions, 30 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 8a6862be9f58..403f05ac1f2a 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -1843,7 +1843,7 @@ static void recovery_request_write(struct mddev *mddev, struct r10bio *r10_bio) | |||
1843 | { | 1843 | { |
1844 | struct r10conf *conf = mddev->private; | 1844 | struct r10conf *conf = mddev->private; |
1845 | int d; | 1845 | int d; |
1846 | struct bio *wbio; | 1846 | struct bio *wbio, *wbio2; |
1847 | 1847 | ||
1848 | if (!test_bit(R10BIO_Uptodate, &r10_bio->state)) { | 1848 | if (!test_bit(R10BIO_Uptodate, &r10_bio->state)) { |
1849 | fix_recovery_read_error(r10_bio); | 1849 | fix_recovery_read_error(r10_bio); |
@@ -1855,12 +1855,20 @@ static void recovery_request_write(struct mddev *mddev, struct r10bio *r10_bio) | |||
1855 | * share the pages with the first bio | 1855 | * share the pages with the first bio |
1856 | * and submit the write request | 1856 | * and submit the write request |
1857 | */ | 1857 | */ |
1858 | wbio = r10_bio->devs[1].bio; | ||
1859 | d = r10_bio->devs[1].devnum; | 1858 | d = r10_bio->devs[1].devnum; |
1860 | 1859 | wbio = r10_bio->devs[1].bio; | |
1861 | atomic_inc(&conf->mirrors[d].rdev->nr_pending); | 1860 | wbio2 = r10_bio->devs[1].repl_bio; |
1862 | md_sync_acct(conf->mirrors[d].rdev->bdev, wbio->bi_size >> 9); | 1861 | if (wbio->bi_end_io) { |
1863 | generic_make_request(wbio); | 1862 | atomic_inc(&conf->mirrors[d].rdev->nr_pending); |
1863 | md_sync_acct(conf->mirrors[d].rdev->bdev, wbio->bi_size >> 9); | ||
1864 | generic_make_request(wbio); | ||
1865 | } | ||
1866 | if (wbio2 && wbio2->bi_end_io) { | ||
1867 | atomic_inc(&conf->mirrors[d].replacement->nr_pending); | ||
1868 | md_sync_acct(conf->mirrors[d].replacement->bdev, | ||
1869 | wbio2->bi_size >> 9); | ||
1870 | generic_make_request(wbio2); | ||
1871 | } | ||
1864 | } | 1872 | } |
1865 | 1873 | ||
1866 | 1874 | ||
@@ -2590,23 +2598,30 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, | |||
2590 | sector_t sect; | 2598 | sector_t sect; |
2591 | int must_sync; | 2599 | int must_sync; |
2592 | int any_working; | 2600 | int any_working; |
2593 | 2601 | struct mirror_info *mirror = &conf->mirrors[i]; | |
2594 | if (conf->mirrors[i].rdev == NULL || | 2602 | |
2595 | test_bit(In_sync, &conf->mirrors[i].rdev->flags)) | 2603 | if ((mirror->rdev == NULL || |
2604 | test_bit(In_sync, &mirror->rdev->flags)) | ||
2605 | && | ||
2606 | (mirror->replacement == NULL || | ||
2607 | test_bit(Faulty, | ||
2608 | &mirror->replacement->flags))) | ||
2596 | continue; | 2609 | continue; |
2597 | 2610 | ||
2598 | still_degraded = 0; | 2611 | still_degraded = 0; |
2599 | /* want to reconstruct this device */ | 2612 | /* want to reconstruct this device */ |
2600 | rb2 = r10_bio; | 2613 | rb2 = r10_bio; |
2601 | sect = raid10_find_virt(conf, sector_nr, i); | 2614 | sect = raid10_find_virt(conf, sector_nr, i); |
2602 | /* Unless we are doing a full sync, we only need | 2615 | /* Unless we are doing a full sync, or a replacement |
2603 | * to recover the block if it is set in the bitmap | 2616 | * we only need to recover the block if it is set in |
2617 | * the bitmap | ||
2604 | */ | 2618 | */ |
2605 | must_sync = bitmap_start_sync(mddev->bitmap, sect, | 2619 | must_sync = bitmap_start_sync(mddev->bitmap, sect, |
2606 | &sync_blocks, 1); | 2620 | &sync_blocks, 1); |
2607 | if (sync_blocks < max_sync) | 2621 | if (sync_blocks < max_sync) |
2608 | max_sync = sync_blocks; | 2622 | max_sync = sync_blocks; |
2609 | if (!must_sync && | 2623 | if (!must_sync && |
2624 | mirror->replacement == NULL && | ||
2610 | !conf->fullsync) { | 2625 | !conf->fullsync) { |
2611 | /* yep, skip the sync_blocks here, but don't assume | 2626 | /* yep, skip the sync_blocks here, but don't assume |
2612 | * that there will never be anything to do here | 2627 | * that there will never be anything to do here |
@@ -2676,33 +2691,60 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, | |||
2676 | bio->bi_end_io = end_sync_read; | 2691 | bio->bi_end_io = end_sync_read; |
2677 | bio->bi_rw = READ; | 2692 | bio->bi_rw = READ; |
2678 | from_addr = r10_bio->devs[j].addr; | 2693 | from_addr = r10_bio->devs[j].addr; |
2679 | bio->bi_sector = from_addr + | 2694 | bio->bi_sector = from_addr + rdev->data_offset; |
2680 | conf->mirrors[d].rdev->data_offset; | 2695 | bio->bi_bdev = rdev->bdev; |
2681 | bio->bi_bdev = conf->mirrors[d].rdev->bdev; | 2696 | atomic_inc(&rdev->nr_pending); |
2682 | atomic_inc(&conf->mirrors[d].rdev->nr_pending); | 2697 | /* and we write to 'i' (if not in_sync) */ |
2683 | atomic_inc(&r10_bio->remaining); | ||
2684 | /* and we write to 'i' */ | ||
2685 | 2698 | ||
2686 | for (k=0; k<conf->copies; k++) | 2699 | for (k=0; k<conf->copies; k++) |
2687 | if (r10_bio->devs[k].devnum == i) | 2700 | if (r10_bio->devs[k].devnum == i) |
2688 | break; | 2701 | break; |
2689 | BUG_ON(k == conf->copies); | 2702 | BUG_ON(k == conf->copies); |
2690 | bio = r10_bio->devs[1].bio; | ||
2691 | bio->bi_next = biolist; | ||
2692 | biolist = bio; | ||
2693 | bio->bi_private = r10_bio; | ||
2694 | bio->bi_end_io = end_sync_write; | ||
2695 | bio->bi_rw = WRITE; | ||
2696 | to_addr = r10_bio->devs[k].addr; | 2703 | to_addr = r10_bio->devs[k].addr; |
2697 | bio->bi_sector = to_addr + | ||
2698 | conf->mirrors[i].rdev->data_offset; | ||
2699 | bio->bi_bdev = conf->mirrors[i].rdev->bdev; | ||
2700 | |||
2701 | r10_bio->devs[0].devnum = d; | 2704 | r10_bio->devs[0].devnum = d; |
2702 | r10_bio->devs[0].addr = from_addr; | 2705 | r10_bio->devs[0].addr = from_addr; |
2703 | r10_bio->devs[1].devnum = i; | 2706 | r10_bio->devs[1].devnum = i; |
2704 | r10_bio->devs[1].addr = to_addr; | 2707 | r10_bio->devs[1].addr = to_addr; |
2705 | 2708 | ||
2709 | rdev = mirror->rdev; | ||
2710 | if (!test_bit(In_sync, &rdev->flags)) { | ||
2711 | bio = r10_bio->devs[1].bio; | ||
2712 | bio->bi_next = biolist; | ||
2713 | biolist = bio; | ||
2714 | bio->bi_private = r10_bio; | ||
2715 | bio->bi_end_io = end_sync_write; | ||
2716 | bio->bi_rw = WRITE; | ||
2717 | bio->bi_sector = to_addr | ||
2718 | + rdev->data_offset; | ||
2719 | bio->bi_bdev = rdev->bdev; | ||
2720 | atomic_inc(&r10_bio->remaining); | ||
2721 | } else | ||
2722 | r10_bio->devs[1].bio->bi_end_io = NULL; | ||
2723 | |||
2724 | /* and maybe write to replacement */ | ||
2725 | bio = r10_bio->devs[1].repl_bio; | ||
2726 | if (bio) | ||
2727 | bio->bi_end_io = NULL; | ||
2728 | rdev = mirror->replacement; | ||
2729 | /* Note: if rdev != NULL, then bio | ||
2730 | * cannot be NULL as r10buf_pool_alloc will | ||
2731 | * have allocated it. | ||
2732 | * So the second test here is pointless. | ||
2733 | * But it keeps semantic-checkers happy, and | ||
2734 | * this comment keeps human reviewers | ||
2735 | * happy. | ||
2736 | */ | ||
2737 | if (rdev == NULL || bio == NULL || | ||
2738 | test_bit(Faulty, &rdev->flags)) | ||
2739 | break; | ||
2740 | bio->bi_next = biolist; | ||
2741 | biolist = bio; | ||
2742 | bio->bi_private = r10_bio; | ||
2743 | bio->bi_end_io = end_sync_write; | ||
2744 | bio->bi_rw = WRITE; | ||
2745 | bio->bi_sector = to_addr + rdev->data_offset; | ||
2746 | bio->bi_bdev = rdev->bdev; | ||
2747 | atomic_inc(&r10_bio->remaining); | ||
2706 | break; | 2748 | break; |
2707 | } | 2749 | } |
2708 | if (j == conf->copies) { | 2750 | if (j == conf->copies) { |
@@ -2720,8 +2762,16 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, | |||
2720 | for (k = 0; k < conf->copies; k++) | 2762 | for (k = 0; k < conf->copies; k++) |
2721 | if (r10_bio->devs[k].devnum == i) | 2763 | if (r10_bio->devs[k].devnum == i) |
2722 | break; | 2764 | break; |
2723 | if (!rdev_set_badblocks( | 2765 | if (!test_bit(In_sync, |
2724 | conf->mirrors[i].rdev, | 2766 | &mirror->rdev->flags) |
2767 | && !rdev_set_badblocks( | ||
2768 | mirror->rdev, | ||
2769 | r10_bio->devs[k].addr, | ||
2770 | max_sync, 0)) | ||
2771 | any_working = 0; | ||
2772 | if (mirror->replacement && | ||
2773 | !rdev_set_badblocks( | ||
2774 | mirror->replacement, | ||
2725 | r10_bio->devs[k].addr, | 2775 | r10_bio->devs[k].addr, |
2726 | max_sync, 0)) | 2776 | max_sync, 0)) |
2727 | any_working = 0; | 2777 | any_working = 0; |
@@ -2732,7 +2782,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, | |||
2732 | printk(KERN_INFO "md/raid10:%s: insufficient " | 2782 | printk(KERN_INFO "md/raid10:%s: insufficient " |
2733 | "working devices for recovery.\n", | 2783 | "working devices for recovery.\n", |
2734 | mdname(mddev)); | 2784 | mdname(mddev)); |
2735 | conf->mirrors[i].recovery_disabled | 2785 | mirror->recovery_disabled |
2736 | = mddev->recovery_disabled; | 2786 | = mddev->recovery_disabled; |
2737 | } | 2787 | } |
2738 | break; | 2788 | break; |