[PATCH] md: fix --re-add for raid1 and raid6

If you have an array with a write-intent-bitmap, and you remove a device, then
re-add it, a full recovery isn't needed. We detect a re-add by looking at
saved_raid_disk. For raid1, it doesn't matter which disk it was, only whether
or not it was an active device. The old code being removed set a value of
'mirror' which was then ignored, so it can go. The changed code performs the
correct check.

For raid6, if there are two missing devices, make sure we chose the right slot
on --re-add rather than always the first slot.

Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

NeilBrown and committed by
Linus Torvalds
6aea114a b2a2703c

+12 -6
+4 -4
drivers/md/raid1.c
··· 953 int mirror = 0; 954 mirror_info_t *p; 955 956 - if (rdev->saved_raid_disk >= 0 && 957 - conf->mirrors[rdev->saved_raid_disk].rdev == NULL) 958 - mirror = rdev->saved_raid_disk; 959 for (mirror=0; mirror < mddev->raid_disks; mirror++) 960 if ( !(p=conf->mirrors+mirror)->rdev) { 961 ··· 969 p->head_position = 0; 970 rdev->raid_disk = mirror; 971 found = 1; 972 - if (rdev->saved_raid_disk != mirror) 973 conf->fullsync = 1; 974 rcu_assign_pointer(p->rdev, rdev); 975 break;
··· 953 int mirror = 0; 954 mirror_info_t *p; 955 956 for (mirror=0; mirror < mddev->raid_disks; mirror++) 957 if ( !(p=conf->mirrors+mirror)->rdev) { 958 ··· 972 p->head_position = 0; 973 rdev->raid_disk = mirror; 974 found = 1; 975 + /* As all devices are equivalent, we don't need a full recovery 976 + * if this was recently any drive of the array 977 + */ 978 + if (rdev->saved_raid_disk < 0) 979 conf->fullsync = 1; 980 rcu_assign_pointer(p->rdev, rdev); 981 break;
+8 -2
drivers/md/raid6main.c
··· 2158 /* no point adding a device */ 2159 return 0; 2160 /* 2161 - * find the disk ... 2162 */ 2163 - for (disk=0; disk < mddev->raid_disks; disk++) 2164 if ((p=conf->disks + disk)->rdev == NULL) { 2165 clear_bit(In_sync, &rdev->flags); 2166 rdev->raid_disk = disk;
··· 2158 /* no point adding a device */ 2159 return 0; 2160 /* 2161 + * find the disk ... but prefer rdev->saved_raid_disk 2162 + * if possible. 2163 */ 2164 + if (rdev->saved_raid_disk >= 0 && 2165 + conf->disks[rdev->saved_raid_disk].rdev == NULL) 2166 + disk = rdev->saved_raid_disk; 2167 + else 2168 + disk = 0; 2169 + for ( ; disk < mddev->raid_disks; disk++) 2170 if ((p=conf->disks + disk)->rdev == NULL) { 2171 clear_bit(In_sync, &rdev->flags); 2172 rdev->raid_disk = disk;