diff options
Diffstat (limited to 'drivers/md/dm-raid.c')
-rw-r--r-- | drivers/md/dm-raid.c | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 2e10c2f13a34..5bfe285ea9d1 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c | |||
@@ -208,6 +208,7 @@ struct raid_dev { | |||
208 | #define RT_FLAG_RS_BITMAP_LOADED 2 | 208 | #define RT_FLAG_RS_BITMAP_LOADED 2 |
209 | #define RT_FLAG_UPDATE_SBS 3 | 209 | #define RT_FLAG_UPDATE_SBS 3 |
210 | #define RT_FLAG_RESHAPE_RS 4 | 210 | #define RT_FLAG_RESHAPE_RS 4 |
211 | #define RT_FLAG_RS_SUSPENDED 5 | ||
211 | 212 | ||
212 | /* Array elements of 64 bit needed for rebuild/failed disk bits */ | 213 | /* Array elements of 64 bit needed for rebuild/failed disk bits */ |
213 | #define DISKS_ARRAY_ELEMS ((MAX_RAID_DEVICES + (sizeof(uint64_t) * 8 - 1)) / sizeof(uint64_t) / 8) | 214 | #define DISKS_ARRAY_ELEMS ((MAX_RAID_DEVICES + (sizeof(uint64_t) * 8 - 1)) / sizeof(uint64_t) / 8) |
@@ -564,9 +565,10 @@ static const char *raid10_md_layout_to_format(int layout) | |||
564 | if (__raid10_near_copies(layout) > 1) | 565 | if (__raid10_near_copies(layout) > 1) |
565 | return "near"; | 566 | return "near"; |
566 | 567 | ||
567 | WARN_ON(__raid10_far_copies(layout) < 2); | 568 | if (__raid10_far_copies(layout) > 1) |
569 | return "far"; | ||
568 | 570 | ||
569 | return "far"; | 571 | return "unknown"; |
570 | } | 572 | } |
571 | 573 | ||
572 | /* Return md raid10 algorithm for @name */ | 574 | /* Return md raid10 algorithm for @name */ |
@@ -2540,11 +2542,6 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) | |||
2540 | if (!freshest) | 2542 | if (!freshest) |
2541 | return 0; | 2543 | return 0; |
2542 | 2544 | ||
2543 | if (validate_raid_redundancy(rs)) { | ||
2544 | rs->ti->error = "Insufficient redundancy to activate array"; | ||
2545 | return -EINVAL; | ||
2546 | } | ||
2547 | |||
2548 | /* | 2545 | /* |
2549 | * Validation of the freshest device provides the source of | 2546 | * Validation of the freshest device provides the source of |
2550 | * validation for the remaining devices. | 2547 | * validation for the remaining devices. |
@@ -2553,6 +2550,11 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) | |||
2553 | if (super_validate(rs, freshest)) | 2550 | if (super_validate(rs, freshest)) |
2554 | return -EINVAL; | 2551 | return -EINVAL; |
2555 | 2552 | ||
2553 | if (validate_raid_redundancy(rs)) { | ||
2554 | rs->ti->error = "Insufficient redundancy to activate array"; | ||
2555 | return -EINVAL; | ||
2556 | } | ||
2557 | |||
2556 | rdev_for_each(rdev, mddev) | 2558 | rdev_for_each(rdev, mddev) |
2557 | if (!test_bit(Journal, &rdev->flags) && | 2559 | if (!test_bit(Journal, &rdev->flags) && |
2558 | rdev != freshest && | 2560 | rdev != freshest && |
@@ -3168,6 +3170,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
3168 | } | 3170 | } |
3169 | 3171 | ||
3170 | mddev_suspend(&rs->md); | 3172 | mddev_suspend(&rs->md); |
3173 | set_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags); | ||
3171 | 3174 | ||
3172 | /* Try to adjust the raid4/5/6 stripe cache size to the stripe size */ | 3175 | /* Try to adjust the raid4/5/6 stripe cache size to the stripe size */ |
3173 | if (rs_is_raid456(rs)) { | 3176 | if (rs_is_raid456(rs)) { |
@@ -3625,7 +3628,7 @@ static void raid_postsuspend(struct dm_target *ti) | |||
3625 | { | 3628 | { |
3626 | struct raid_set *rs = ti->private; | 3629 | struct raid_set *rs = ti->private; |
3627 | 3630 | ||
3628 | if (!rs->md.suspended) | 3631 | if (!test_and_set_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) |
3629 | mddev_suspend(&rs->md); | 3632 | mddev_suspend(&rs->md); |
3630 | 3633 | ||
3631 | rs->md.ro = 1; | 3634 | rs->md.ro = 1; |
@@ -3759,7 +3762,7 @@ static int rs_start_reshape(struct raid_set *rs) | |||
3759 | return r; | 3762 | return r; |
3760 | 3763 | ||
3761 | /* Need to be resumed to be able to start reshape, recovery is frozen until raid_resume() though */ | 3764 | /* Need to be resumed to be able to start reshape, recovery is frozen until raid_resume() though */ |
3762 | if (mddev->suspended) | 3765 | if (test_and_clear_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) |
3763 | mddev_resume(mddev); | 3766 | mddev_resume(mddev); |
3764 | 3767 | ||
3765 | /* | 3768 | /* |
@@ -3786,8 +3789,8 @@ static int rs_start_reshape(struct raid_set *rs) | |||
3786 | } | 3789 | } |
3787 | 3790 | ||
3788 | /* Suspend because a resume will happen in raid_resume() */ | 3791 | /* Suspend because a resume will happen in raid_resume() */ |
3789 | if (!mddev->suspended) | 3792 | set_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags); |
3790 | mddev_suspend(mddev); | 3793 | mddev_suspend(mddev); |
3791 | 3794 | ||
3792 | /* | 3795 | /* |
3793 | * Now reshape got set up, update superblocks to | 3796 | * Now reshape got set up, update superblocks to |
@@ -3883,13 +3886,13 @@ static void raid_resume(struct dm_target *ti) | |||
3883 | if (!(rs->ctr_flags & RESUME_STAY_FROZEN_FLAGS)) | 3886 | if (!(rs->ctr_flags & RESUME_STAY_FROZEN_FLAGS)) |
3884 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); | 3887 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
3885 | 3888 | ||
3886 | if (mddev->suspended) | 3889 | if (test_and_clear_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) |
3887 | mddev_resume(mddev); | 3890 | mddev_resume(mddev); |
3888 | } | 3891 | } |
3889 | 3892 | ||
3890 | static struct target_type raid_target = { | 3893 | static struct target_type raid_target = { |
3891 | .name = "raid", | 3894 | .name = "raid", |
3892 | .version = {1, 11, 1}, | 3895 | .version = {1, 12, 1}, |
3893 | .module = THIS_MODULE, | 3896 | .module = THIS_MODULE, |
3894 | .ctr = raid_ctr, | 3897 | .ctr = raid_ctr, |
3895 | .dtr = raid_dtr, | 3898 | .dtr = raid_dtr, |