diff options
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 4edcda8f4869..4869128bf742 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -3001,6 +3001,9 @@ level_store(mddev_t *mddev, const char *buf, size_t len) | |||
3001 | return -EINVAL; | 3001 | return -EINVAL; |
3002 | } | 3002 | } |
3003 | 3003 | ||
3004 | list_for_each_entry(rdev, &mddev->disks, same_set) | ||
3005 | rdev->new_raid_disk = rdev->raid_disk; | ||
3006 | |||
3004 | /* ->takeover must set new_* and/or delta_disks | 3007 | /* ->takeover must set new_* and/or delta_disks |
3005 | * if it succeeds, and may set them when it fails. | 3008 | * if it succeeds, and may set them when it fails. |
3006 | */ | 3009 | */ |
@@ -3051,13 +3054,35 @@ level_store(mddev_t *mddev, const char *buf, size_t len) | |||
3051 | mddev->safemode = 0; | 3054 | mddev->safemode = 0; |
3052 | } | 3055 | } |
3053 | 3056 | ||
3054 | module_put(mddev->pers->owner); | 3057 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
3055 | /* Invalidate devices that are now superfluous */ | 3058 | char nm[20]; |
3056 | list_for_each_entry(rdev, &mddev->disks, same_set) | 3059 | if (rdev->raid_disk < 0) |
3057 | if (rdev->raid_disk >= mddev->raid_disks) { | 3060 | continue; |
3058 | rdev->raid_disk = -1; | 3061 | if (rdev->new_raid_disk > mddev->raid_disks) |
3062 | rdev->new_raid_disk = -1; | ||
3063 | if (rdev->new_raid_disk == rdev->raid_disk) | ||
3064 | continue; | ||
3065 | sprintf(nm, "rd%d", rdev->raid_disk); | ||
3066 | sysfs_remove_link(&mddev->kobj, nm); | ||
3067 | } | ||
3068 | list_for_each_entry(rdev, &mddev->disks, same_set) { | ||
3069 | if (rdev->raid_disk < 0) | ||
3070 | continue; | ||
3071 | if (rdev->new_raid_disk == rdev->raid_disk) | ||
3072 | continue; | ||
3073 | rdev->raid_disk = rdev->new_raid_disk; | ||
3074 | if (rdev->raid_disk < 0) | ||
3059 | clear_bit(In_sync, &rdev->flags); | 3075 | clear_bit(In_sync, &rdev->flags); |
3076 | else { | ||
3077 | char nm[20]; | ||
3078 | sprintf(nm, "rd%d", rdev->raid_disk); | ||
3079 | if(sysfs_create_link(&mddev->kobj, &rdev->kobj, nm)) | ||
3080 | printk("md: cannot register %s for %s after level change\n", | ||
3081 | nm, mdname(mddev)); | ||
3060 | } | 3082 | } |
3083 | } | ||
3084 | |||
3085 | module_put(mddev->pers->owner); | ||
3061 | mddev->pers = pers; | 3086 | mddev->pers = pers; |
3062 | mddev->private = priv; | 3087 | mddev->private = priv; |
3063 | strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel)); | 3088 | strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel)); |