@@ -1843,7 +1843,7 @@ static void recovery_request_write(struct mddev *mddev, struct r10bio *r10_bio)
1843
1843
{
1844
1844
struct r10conf * conf = mddev -> private ;
1845
1845
int d ;
1846
- struct bio * wbio ;
1846
+ struct bio * wbio , * wbio2 ;
1847
1847
1848
1848
if (!test_bit (R10BIO_Uptodate , & r10_bio -> state )) {
1849
1849
fix_recovery_read_error (r10_bio );
@@ -1855,12 +1855,20 @@ static void recovery_request_write(struct mddev *mddev, struct r10bio *r10_bio)
1855
1855
* share the pages with the first bio
1856
1856
* and submit the write request
1857
1857
*/
1858
- wbio = r10_bio -> devs [1 ].bio ;
1859
1858
d = r10_bio -> devs [1 ].devnum ;
1860
-
1861
- atomic_inc (& conf -> mirrors [d ].rdev -> nr_pending );
1862
- md_sync_acct (conf -> mirrors [d ].rdev -> bdev , wbio -> bi_size >> 9 );
1863
- generic_make_request (wbio );
1859
+ wbio = r10_bio -> devs [1 ].bio ;
1860
+ wbio2 = r10_bio -> devs [1 ].repl_bio ;
1861
+ if (wbio -> bi_end_io ) {
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
2598
sector_t sect ;
2591
2599
int must_sync ;
2592
2600
int any_working ;
2593
-
2594
- if (conf -> mirrors [i ].rdev == NULL ||
2595
- test_bit (In_sync , & conf -> mirrors [i ].rdev -> flags ))
2601
+ struct mirror_info * mirror = & conf -> mirrors [i ];
2602
+
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
2609
continue ;
2597
2610
2598
2611
still_degraded = 0 ;
2599
2612
/* want to reconstruct this device */
2600
2613
rb2 = r10_bio ;
2601
2614
sect = raid10_find_virt (conf , sector_nr , i );
2602
- /* Unless we are doing a full sync, we only need
2603
- * to recover the block if it is set in the bitmap
2615
+ /* Unless we are doing a full sync, or a replacement
2616
+ * we only need to recover the block if it is set in
2617
+ * the bitmap
2604
2618
*/
2605
2619
must_sync = bitmap_start_sync (mddev -> bitmap , sect ,
2606
2620
& sync_blocks , 1 );
2607
2621
if (sync_blocks < max_sync )
2608
2622
max_sync = sync_blocks ;
2609
2623
if (!must_sync &&
2624
+ mirror -> replacement == NULL &&
2610
2625
!conf -> fullsync ) {
2611
2626
/* yep, skip the sync_blocks here, but don't assume
2612
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
2691
bio -> bi_end_io = end_sync_read ;
2677
2692
bio -> bi_rw = READ ;
2678
2693
from_addr = r10_bio -> devs [j ].addr ;
2679
- bio -> bi_sector = from_addr +
2680
- conf -> mirrors [d ].rdev -> data_offset ;
2681
- bio -> bi_bdev = conf -> mirrors [d ].rdev -> bdev ;
2682
- atomic_inc (& conf -> mirrors [d ].rdev -> nr_pending );
2683
- atomic_inc (& r10_bio -> remaining );
2684
- /* and we write to 'i' */
2694
+ bio -> bi_sector = from_addr + rdev -> data_offset ;
2695
+ bio -> bi_bdev = rdev -> bdev ;
2696
+ atomic_inc (& rdev -> nr_pending );
2697
+ /* and we write to 'i' (if not in_sync) */
2685
2698
2686
2699
for (k = 0 ; k < conf -> copies ; k ++ )
2687
2700
if (r10_bio -> devs [k ].devnum == i )
2688
2701
break ;
2689
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
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
2704
r10_bio -> devs [0 ].devnum = d ;
2702
2705
r10_bio -> devs [0 ].addr = from_addr ;
2703
2706
r10_bio -> devs [1 ].devnum = i ;
2704
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
2748
break ;
2707
2749
}
2708
2750
if (j == conf -> copies ) {
@@ -2720,8 +2762,16 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
2720
2762
for (k = 0 ; k < conf -> copies ; k ++ )
2721
2763
if (r10_bio -> devs [k ].devnum == i )
2722
2764
break ;
2723
- if (!rdev_set_badblocks (
2724
- conf -> mirrors [i ].rdev ,
2765
+ if (!test_bit (In_sync ,
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
2775
r10_bio -> devs [k ].addr ,
2726
2776
max_sync , 0 ))
2727
2777
any_working = 0 ;
@@ -2732,7 +2782,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
2732
2782
printk (KERN_INFO "md/raid10:%s: insufficient "
2733
2783
"working devices for recovery.\n" ,
2734
2784
mdname (mddev ));
2735
- conf -> mirrors [ i ]. recovery_disabled
2785
+ mirror -> recovery_disabled
2736
2786
= mddev -> recovery_disabled ;
2737
2787
}
2738
2788
break ;
0 commit comments