aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2010-05-01 21:09:05 -0400
committerNeilBrown <neilb@suse.de>2010-05-18 01:27:57 -0400
commitf1b29bcae116409db5e543622aadab43041c9ae9 (patch)
tree05dff62e747d8f0c91d6bd38ce900c0083dcbc98 /drivers/md/raid5.c
parente555190d82c0f58e825e3cbd9e6ebe2e7ac713bd (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.c32
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
5613static void *raid5_takeover_raid0(mddev_t *mddev) 5613static 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)
5749static void *raid5_takeover(mddev_t *mddev) 5756static 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
5781static void *raid4_takeover(mddev_t *mddev) 5779static 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;