diff options
author | Dan Williams <dan.j.williams@intel.com> | 2010-05-01 21:09:05 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2010-05-18 01:27:57 -0400 |
commit | f1b29bcae116409db5e543622aadab43041c9ae9 (patch) | |
tree | 05dff62e747d8f0c91d6bd38ce900c0083dcbc98 /drivers/md/raid5.c | |
parent | e555190d82c0f58e825e3cbd9e6ebe2e7ac713bd (diff) |
md/raid4: permit raid0 takeover
For consistency allow raid4 to takeover raid0 in addition to raid5 (with a
raid4 layout).
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/md/raid5.c')
-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; |