aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-12-22 18:17:55 -0500
committerNeilBrown <neilb@suse.de>2011-12-22 18:17:55 -0500
commit24afd80d99f80a79d8824d2805114b8b067e9823 (patch)
treec4ba36331ee56c64ba74a69ec5d0b56b6e860832 /drivers/md
parent9ad1aefc8ae8d2e482b4cc4b7199e2354148bbdc (diff)
md/raid10: handle recovery of replacement devices.
If there is a replacement device, then recover to it, reading from any drives - maybe the one being replaced, maybe not. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/raid10.c110
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;