aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-12-23 10:17:55 +1100
committerNeilBrown <neilb@suse.de>2011-12-23 10:17:55 +1100
commit56a2559bb654ae2555b2ae3b29c837615d0c45c9 (patch)
treef90a0d605260f668ad13af654f7951bcb27dfe64 /drivers/md
parentmd/raid10: Allow replacement device to be replace old drive. (diff)
downloadlinux-dev-56a2559bb654ae2555b2ae3b29c837615d0c45c9.tar.xz
linux-dev-56a2559bb654ae2555b2ae3b29c837615d0c45c9.zip
md/raid10: recognise replacements when assembling array.
If a Replacement is seen, file it as such. If we see two replacements (or two normal devices) for the one slot, abort. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/raid10.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 90e951730a23..011827d0df25 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -3201,6 +3201,16 @@ static int run(struct mddev *mddev)
continue;
disk = conf->mirrors + disk_idx;
+ if (test_bit(Replacement, &rdev->flags)) {
+ if (disk->replacement)
+ goto out_free_conf;
+ disk->replacement = rdev;
+ } else {
+ if (disk->rdev)
+ goto out_free_conf;
+ disk->rdev = rdev;
+ }
+
disk->rdev = rdev;
disk_stack_limits(mddev->gendisk, rdev->bdev,
rdev->data_offset << 9);
@@ -3228,6 +3238,13 @@ static int run(struct mddev *mddev)
disk = conf->mirrors + i;
+ if (!disk->rdev && disk->replacement) {
+ /* The replacement is all we have - use it */
+ disk->rdev = disk->replacement;
+ disk->replacement = NULL;
+ clear_bit(Replacement, &disk->rdev->flags);
+ }
+
if (!disk->rdev ||
!test_bit(In_sync, &disk->rdev->flags)) {
disk->head_position = 0;