@@ -1757,6 +1757,44 @@ static int raid1_spare_active(struct mddev *mddev)
17571757 return count ;
17581758}
17591759
1760+ static bool raid1_add_conf (struct r1conf * conf , struct md_rdev * rdev , int disk ,
1761+ bool replacement )
1762+ {
1763+ struct raid1_info * info = conf -> mirrors + disk ;
1764+
1765+ if (replacement )
1766+ info += conf -> raid_disks ;
1767+
1768+ if (info -> rdev )
1769+ return false;
1770+
1771+ rdev -> raid_disk = disk ;
1772+ info -> head_position = 0 ;
1773+ info -> seq_start = MaxSector ;
1774+ WRITE_ONCE (info -> rdev , rdev );
1775+
1776+ return true;
1777+ }
1778+
1779+ static bool raid1_remove_conf (struct r1conf * conf , int disk )
1780+ {
1781+ struct raid1_info * info = conf -> mirrors + disk ;
1782+ struct md_rdev * rdev = info -> rdev ;
1783+
1784+ if (!rdev || test_bit (In_sync , & rdev -> flags ) ||
1785+ atomic_read (& rdev -> nr_pending ))
1786+ return false;
1787+
1788+ /* Only remove non-faulty devices if recovery is not possible. */
1789+ if (!test_bit (Faulty , & rdev -> flags ) &&
1790+ rdev -> mddev -> recovery_disabled != conf -> recovery_disabled &&
1791+ rdev -> mddev -> degraded < conf -> raid_disks )
1792+ return false;
1793+
1794+ WRITE_ONCE (info -> rdev , NULL );
1795+ return true;
1796+ }
1797+
17601798static int raid1_add_disk (struct mddev * mddev , struct md_rdev * rdev )
17611799{
17621800 struct r1conf * conf = mddev -> private ;
@@ -1792,15 +1830,13 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
17921830 disk_stack_limits (mddev -> gendisk , rdev -> bdev ,
17931831 rdev -> data_offset << 9 );
17941832
1795- p -> head_position = 0 ;
1796- rdev -> raid_disk = mirror ;
1833+ raid1_add_conf (conf , rdev , mirror , false);
17971834 err = 0 ;
17981835 /* As all devices are equivalent, we don't need a full recovery
17991836 * if this was recently any drive of the array
18001837 */
18011838 if (rdev -> saved_raid_disk < 0 )
18021839 conf -> fullsync = 1 ;
1803- WRITE_ONCE (p -> rdev , rdev );
18041840 break ;
18051841 }
18061842 if (test_bit (WantReplacement , & p -> rdev -> flags ) &&
@@ -1810,13 +1846,11 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
18101846
18111847 if (err && repl_slot >= 0 ) {
18121848 /* Add this device as a replacement */
1813- p = conf -> mirrors + repl_slot ;
18141849 clear_bit (In_sync , & rdev -> flags );
18151850 set_bit (Replacement , & rdev -> flags );
1816- rdev -> raid_disk = repl_slot ;
1851+ raid1_add_conf ( conf , rdev , repl_slot , true) ;
18171852 err = 0 ;
18181853 conf -> fullsync = 1 ;
1819- WRITE_ONCE (p [conf -> raid_disks ].rdev , rdev );
18201854 }
18211855
18221856 print_conf (conf );
@@ -1833,27 +1867,20 @@ static int raid1_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
18331867 if (unlikely (number >= conf -> raid_disks ))
18341868 goto abort ;
18351869
1836- if (rdev != p -> rdev )
1837- p = conf -> mirrors + conf -> raid_disks + number ;
1870+ if (rdev != p -> rdev ) {
1871+ number += conf -> raid_disks ;
1872+ p = conf -> mirrors + number ;
1873+ }
18381874
18391875 print_conf (conf );
18401876 if (rdev == p -> rdev ) {
1841- if (test_bit (In_sync , & rdev -> flags ) ||
1842- atomic_read (& rdev -> nr_pending )) {
1843- err = - EBUSY ;
1844- goto abort ;
1845- }
1846- /* Only remove non-faulty devices if recovery
1847- * is not possible.
1848- */
1849- if (!test_bit (Faulty , & rdev -> flags ) &&
1850- mddev -> recovery_disabled != conf -> recovery_disabled &&
1851- mddev -> degraded < conf -> raid_disks ) {
1877+ if (!raid1_remove_conf (conf , number )) {
18521878 err = - EBUSY ;
18531879 goto abort ;
18541880 }
1855- WRITE_ONCE (p -> rdev , NULL );
1856- if (conf -> mirrors [conf -> raid_disks + number ].rdev ) {
1881+
1882+ if (number < conf -> raid_disks &&
1883+ conf -> mirrors [conf -> raid_disks + number ].rdev ) {
18571884 /* We just removed a device that is being replaced.
18581885 * Move down the replacement. We drain all IO before
18591886 * doing this to avoid confusion.
@@ -2994,23 +3021,17 @@ static struct r1conf *setup_conf(struct mddev *mddev)
29943021
29953022 err = - EINVAL ;
29963023 spin_lock_init (& conf -> device_lock );
3024+ conf -> raid_disks = mddev -> raid_disks ;
29973025 rdev_for_each (rdev , mddev ) {
29983026 int disk_idx = rdev -> raid_disk ;
2999- if ( disk_idx >= mddev -> raid_disks
3000- || disk_idx < 0 )
3027+
3028+ if ( disk_idx >= conf -> raid_disks || disk_idx < 0 )
30013029 continue ;
3002- if (test_bit (Replacement , & rdev -> flags ))
3003- disk = conf -> mirrors + mddev -> raid_disks + disk_idx ;
3004- else
3005- disk = conf -> mirrors + disk_idx ;
30063030
3007- if (disk -> rdev )
3031+ if (!raid1_add_conf (conf , rdev , disk_idx ,
3032+ test_bit (Replacement , & rdev -> flags )))
30083033 goto abort ;
3009- disk -> rdev = rdev ;
3010- disk -> head_position = 0 ;
3011- disk -> seq_start = MaxSector ;
30123034 }
3013- conf -> raid_disks = mddev -> raid_disks ;
30143035 conf -> mddev = mddev ;
30153036 INIT_LIST_HEAD (& conf -> retry_list );
30163037 INIT_LIST_HEAD (& conf -> bio_end_io_list );
0 commit comments