aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/md.c62
1 files changed, 32 insertions, 30 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 2920fd004865..58f531f8dcc2 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -3280,9 +3280,9 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
3280{ 3280{
3281 char clevel[16]; 3281 char clevel[16];
3282 ssize_t rv = len; 3282 ssize_t rv = len;
3283 struct md_personality *pers; 3283 struct md_personality *pers, *oldpers;
3284 long level; 3284 long level;
3285 void *priv; 3285 void *priv, *oldpriv;
3286 struct md_rdev *rdev; 3286 struct md_rdev *rdev;
3287 3287
3288 if (mddev->pers == NULL) { 3288 if (mddev->pers == NULL) {
@@ -3374,9 +3374,35 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
3374 /* Looks like we have a winner */ 3374 /* Looks like we have a winner */
3375 mddev_suspend(mddev); 3375 mddev_suspend(mddev);
3376 mddev_detach(mddev); 3376 mddev_detach(mddev);
3377 mddev->pers->free(mddev, mddev->private); 3377 oldpers = mddev->pers;
3378 oldpriv = mddev->private;
3379 mddev->pers = pers;
3380 mddev->private = priv;
3381 strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
3382 mddev->level = mddev->new_level;
3383 mddev->layout = mddev->new_layout;
3384 mddev->chunk_sectors = mddev->new_chunk_sectors;
3385 mddev->delta_disks = 0;
3386 mddev->reshape_backwards = 0;
3387 mddev->degraded = 0;
3388
3389 if (oldpers->sync_request == NULL &&
3390 mddev->external) {
3391 /* We are converting from a no-redundancy array
3392 * to a redundancy array and metadata is managed
3393 * externally so we need to be sure that writes
3394 * won't block due to a need to transition
3395 * clean->dirty
3396 * until external management is started.
3397 */
3398 mddev->in_sync = 0;
3399 mddev->safemode_delay = 0;
3400 mddev->safemode = 0;
3401 }
3378 3402
3379 if (mddev->pers->sync_request == NULL && 3403 oldpers->free(mddev, oldpriv);
3404
3405 if (oldpers->sync_request == NULL &&
3380 pers->sync_request != NULL) { 3406 pers->sync_request != NULL) {
3381 /* need to add the md_redundancy_group */ 3407 /* need to add the md_redundancy_group */
3382 if (sysfs_create_group(&mddev->kobj, &md_redundancy_group)) 3408 if (sysfs_create_group(&mddev->kobj, &md_redundancy_group))
@@ -3385,27 +3411,13 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
3385 mdname(mddev)); 3411 mdname(mddev));
3386 mddev->sysfs_action = sysfs_get_dirent(mddev->kobj.sd, "sync_action"); 3412 mddev->sysfs_action = sysfs_get_dirent(mddev->kobj.sd, "sync_action");
3387 } 3413 }
3388 if (mddev->pers->sync_request != NULL && 3414 if (oldpers->sync_request != NULL &&
3389 pers->sync_request == NULL) { 3415 pers->sync_request == NULL) {
3390 /* need to remove the md_redundancy_group */ 3416 /* need to remove the md_redundancy_group */
3391 if (mddev->to_remove == NULL) 3417 if (mddev->to_remove == NULL)
3392 mddev->to_remove = &md_redundancy_group; 3418 mddev->to_remove = &md_redundancy_group;
3393 } 3419 }
3394 3420
3395 if (mddev->pers->sync_request == NULL &&
3396 mddev->external) {
3397 /* We are converting from a no-redundancy array
3398 * to a redundancy array and metadata is managed
3399 * externally so we need to be sure that writes
3400 * won't block due to a need to transition
3401 * clean->dirty
3402 * until external management is started.
3403 */
3404 mddev->in_sync = 0;
3405 mddev->safemode_delay = 0;
3406 mddev->safemode = 0;
3407 }
3408
3409 rdev_for_each(rdev, mddev) { 3421 rdev_for_each(rdev, mddev) {
3410 if (rdev->raid_disk < 0) 3422 if (rdev->raid_disk < 0)
3411 continue; 3423 continue;
@@ -3431,17 +3443,7 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
3431 } 3443 }
3432 } 3444 }
3433 3445
3434 module_put(mddev->pers->owner); 3446 if (pers->sync_request == NULL) {
3435 mddev->pers = pers;
3436 mddev->private = priv;
3437 strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
3438 mddev->level = mddev->new_level;
3439 mddev->layout = mddev->new_layout;
3440 mddev->chunk_sectors = mddev->new_chunk_sectors;
3441 mddev->delta_disks = 0;
3442 mddev->reshape_backwards = 0;
3443 mddev->degraded = 0;
3444 if (mddev->pers->sync_request == NULL) {
3445 /* this is now an array without redundancy, so 3447 /* this is now an array without redundancy, so
3446 * it must always be in_sync 3448 * it must always be in_sync
3447 */ 3449 */