diff options
author | NeilBrown <neilb@suse.de> | 2005-11-28 16:44:13 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-28 17:42:26 -0500 |
commit | 6aea114a728db9296f42102d4885e7fb035de0a9 (patch) | |
tree | fa03f942fea0fef446a10cba423f2eee890c5d89 /drivers | |
parent | b2a2703c282ce77d189a250f58039daac1da3314 (diff) |
[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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/md/raid1.c | 8 | ||||
-rw-r--r-- | drivers/md/raid6main.c | 10 |
2 files changed, 12 insertions, 6 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 2da9d3ba902d..3066c587b539 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -953,9 +953,6 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
953 | int mirror = 0; | 953 | int mirror = 0; |
954 | mirror_info_t *p; | 954 | mirror_info_t *p; |
955 | 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++) | 956 | for (mirror=0; mirror < mddev->raid_disks; mirror++) |
960 | if ( !(p=conf->mirrors+mirror)->rdev) { | 957 | if ( !(p=conf->mirrors+mirror)->rdev) { |
961 | 958 | ||
@@ -972,7 +969,10 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
972 | p->head_position = 0; | 969 | p->head_position = 0; |
973 | rdev->raid_disk = mirror; | 970 | rdev->raid_disk = mirror; |
974 | found = 1; | 971 | found = 1; |
975 | if (rdev->saved_raid_disk != mirror) | 972 | /* As all devices are equivalent, we don't need a full recovery |
973 | * if this was recently any drive of the array | ||
974 | */ | ||
975 | if (rdev->saved_raid_disk < 0) | ||
976 | conf->fullsync = 1; | 976 | conf->fullsync = 1; |
977 | rcu_assign_pointer(p->rdev, rdev); | 977 | rcu_assign_pointer(p->rdev, rdev); |
978 | break; | 978 | break; |
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index 00da37848d05..0000d162d198 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c | |||
@@ -2158,9 +2158,15 @@ static int raid6_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
2158 | /* no point adding a device */ | 2158 | /* no point adding a device */ |
2159 | return 0; | 2159 | return 0; |
2160 | /* | 2160 | /* |
2161 | * find the disk ... | 2161 | * find the disk ... but prefer rdev->saved_raid_disk |
2162 | * if possible. | ||
2162 | */ | 2163 | */ |
2163 | for (disk=0; disk < mddev->raid_disks; disk++) | 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++) | ||
2164 | if ((p=conf->disks + disk)->rdev == NULL) { | 2170 | if ((p=conf->disks + disk)->rdev == NULL) { |
2165 | clear_bit(In_sync, &rdev->flags); | 2171 | clear_bit(In_sync, &rdev->flags); |
2166 | rdev->raid_disk = disk; | 2172 | rdev->raid_disk = disk; |