diff options
| -rw-r--r-- | drivers/md/raid5.c | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 2882a26646fd..81563b7c0357 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -5610,10 +5610,17 @@ static void raid5_quiesce(mddev_t *mddev, int state) | |||
| 5610 | } | 5610 | } |
| 5611 | 5611 | ||
| 5612 | 5612 | ||
| 5613 | static void *raid5_takeover_raid0(mddev_t *mddev) | 5613 | static void *raid45_takeover_raid0(mddev_t *mddev, int level) |
| 5614 | { | 5614 | { |
| 5615 | struct raid0_private_data *raid0_priv = mddev->private; | ||
| 5615 | 5616 | ||
| 5616 | mddev->new_level = 5; | 5617 | /* for raid0 takeover only one zone is supported */ |
| 5618 | if (raid0_priv->nr_strip_zones > 1) { | ||
| 5619 | printk(KERN_ERR "md: cannot takeover raid0 with more than one zone.\n"); | ||
| 5620 | return ERR_PTR(-EINVAL); | ||
| 5621 | } | ||
| 5622 | |||
| 5623 | mddev->new_level = level; | ||
| 5617 | mddev->new_layout = ALGORITHM_PARITY_N; | 5624 | mddev->new_layout = ALGORITHM_PARITY_N; |
| 5618 | mddev->new_chunk_sectors = mddev->chunk_sectors; | 5625 | mddev->new_chunk_sectors = mddev->chunk_sectors; |
| 5619 | mddev->raid_disks += 1; | 5626 | mddev->raid_disks += 1; |
| @@ -5749,22 +5756,13 @@ static int raid6_check_reshape(mddev_t *mddev) | |||
| 5749 | static void *raid5_takeover(mddev_t *mddev) | 5756 | static void *raid5_takeover(mddev_t *mddev) |
| 5750 | { | 5757 | { |
| 5751 | /* raid5 can take over: | 5758 | /* raid5 can take over: |
| 5752 | * raid0 - if all devices are the same - make it a raid4 layout | 5759 | * raid0 - if there is only one strip zone - make it a raid4 layout |
| 5753 | * raid1 - if there are two drives. We need to know the chunk size | 5760 | * raid1 - if there are two drives. We need to know the chunk size |
| 5754 | * raid4 - trivial - just use a raid4 layout. | 5761 | * raid4 - trivial - just use a raid4 layout. |
| 5755 | * raid6 - Providing it is a *_6 layout | 5762 | * raid6 - Providing it is a *_6 layout |
| 5756 | */ | 5763 | */ |
| 5757 | if (mddev->level == 0) { | 5764 | if (mddev->level == 0) |
| 5758 | /* for raid0 takeover only one zone is supported */ | 5765 | return raid45_takeover_raid0(mddev, 5); |
| 5759 | struct raid0_private_data *raid0_priv | ||
| 5760 | = mddev->private; | ||
| 5761 | if (raid0_priv->nr_strip_zones > 1) { | ||
| 5762 | printk(KERN_ERR "md: cannot takeover raid 0 with more than one zone.\n"); | ||
| 5763 | return ERR_PTR(-EINVAL); | ||
| 5764 | } | ||
| 5765 | return raid5_takeover_raid0(mddev); | ||
| 5766 | } | ||
| 5767 | |||
| 5768 | if (mddev->level == 1) | 5766 | if (mddev->level == 1) |
| 5769 | return raid5_takeover_raid1(mddev); | 5767 | return raid5_takeover_raid1(mddev); |
| 5770 | if (mddev->level == 4) { | 5768 | if (mddev->level == 4) { |
| @@ -5780,8 +5778,12 @@ static void *raid5_takeover(mddev_t *mddev) | |||
| 5780 | 5778 | ||
| 5781 | static void *raid4_takeover(mddev_t *mddev) | 5779 | static void *raid4_takeover(mddev_t *mddev) |
| 5782 | { | 5780 | { |
| 5783 | /* raid4 can take over raid5 if layout is right. | 5781 | /* raid4 can take over: |
| 5782 | * raid0 - if there is only one strip zone | ||
| 5783 | * raid5 - if layout is right | ||
| 5784 | */ | 5784 | */ |
| 5785 | if (mddev->level == 0) | ||
| 5786 | return raid45_takeover_raid0(mddev, 4); | ||
| 5785 | if (mddev->level == 5 && | 5787 | if (mddev->level == 5 && |
| 5786 | mddev->layout == ALGORITHM_PARITY_N) { | 5788 | mddev->layout == ALGORITHM_PARITY_N) { |
| 5787 | mddev->new_layout = 0; | 5789 | mddev->new_layout = 0; |
