浏览代码

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>
Dan Williams 15 年之前
父节点
当前提交
f1b29bcae1
共有 1 个文件被更改,包括 17 次插入15 次删除
  1. 17 15
      drivers/md/raid5.c

+ 17 - 15
drivers/md/raid5.c

@@ -5610,10 +5610,17 @@ static void raid5_quiesce(mddev_t *mddev, int state)
 }
 }
 
 
 
 
-static void *raid5_takeover_raid0(mddev_t *mddev)
+static void *raid45_takeover_raid0(mddev_t *mddev, int level)
 {
 {
+	struct raid0_private_data *raid0_priv = mddev->private;
 
 
-	mddev->new_level = 5;
+	/* for raid0 takeover only one zone is supported */
+	if (raid0_priv->nr_strip_zones > 1) {
+		printk(KERN_ERR "md: cannot takeover raid0 with more than one zone.\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	mddev->new_level = level;
 	mddev->new_layout = ALGORITHM_PARITY_N;
 	mddev->new_layout = ALGORITHM_PARITY_N;
 	mddev->new_chunk_sectors = mddev->chunk_sectors;
 	mddev->new_chunk_sectors = mddev->chunk_sectors;
 	mddev->raid_disks += 1;
 	mddev->raid_disks += 1;
@@ -5749,22 +5756,13 @@ static int raid6_check_reshape(mddev_t *mddev)
 static void *raid5_takeover(mddev_t *mddev)
 static void *raid5_takeover(mddev_t *mddev)
 {
 {
 	/* raid5 can take over:
 	/* raid5 can take over:
-	 *  raid0 - if all devices are the same - make it a raid4 layout
+	 *  raid0 - if there is only one strip zone - make it a raid4 layout
 	 *  raid1 - if there are two drives.  We need to know the chunk size
 	 *  raid1 - if there are two drives.  We need to know the chunk size
 	 *  raid4 - trivial - just use a raid4 layout.
 	 *  raid4 - trivial - just use a raid4 layout.
 	 *  raid6 - Providing it is a *_6 layout
 	 *  raid6 - Providing it is a *_6 layout
 	 */
 	 */
-	if (mddev->level == 0) {
-		/* for raid0 takeover only one zone is supported */
-		struct raid0_private_data *raid0_priv
-			= mddev->private;
-		if (raid0_priv->nr_strip_zones > 1) {
-			printk(KERN_ERR "md: cannot takeover raid 0 with more than one zone.\n");
-			return ERR_PTR(-EINVAL);
-		}
-		return raid5_takeover_raid0(mddev);
-	}
-
+	if (mddev->level == 0)
+		return raid45_takeover_raid0(mddev, 5);
 	if (mddev->level == 1)
 	if (mddev->level == 1)
 		return raid5_takeover_raid1(mddev);
 		return raid5_takeover_raid1(mddev);
 	if (mddev->level == 4) {
 	if (mddev->level == 4) {
@@ -5780,8 +5778,12 @@ static void *raid5_takeover(mddev_t *mddev)
 
 
 static void *raid4_takeover(mddev_t *mddev)
 static void *raid4_takeover(mddev_t *mddev)
 {
 {
-	/* raid4 can take over raid5 if layout is right.
+	/* raid4 can take over:
+	 *  raid0 - if there is only one strip zone
+	 *  raid5 - if layout is right
 	 */
 	 */
+	if (mddev->level == 0)
+		return raid45_takeover_raid0(mddev, 4);
 	if (mddev->level == 5 &&
 	if (mddev->level == 5 &&
 	    mddev->layout == ALGORITHM_PARITY_N) {
 	    mddev->layout == ALGORITHM_PARITY_N) {
 		mddev->new_layout = 0;
 		mddev->new_layout = 0;