Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 54071b38 authored by Trela Maciej's avatar Trela Maciej Committed by NeilBrown
Browse files

md:Add support for Raid0->Raid5 takeover



Signed-off-by: default avatarMaciej Trela <maciej.trela@intel.com>
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent 84707f38
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -3017,6 +3017,20 @@ level_store(mddev_t *mddev, const char *buf, size_t len)
			mddev->to_remove = &md_redundancy_group;
	}

	if (mddev->pers->sync_request == NULL &&
	    mddev->external) {
		/* We are converting from a no-redundancy array
		 * to a redundancy array and metadata is managed
		 * externally so we need to be sure that writes
		 * won't block due to a need to transition
		 *      clean->dirty
		 * until external management is started.
		 */
		mddev->in_sync = 0;
		mddev->safemode_delay = 0;
		mddev->safemode = 0;
	}

	module_put(mddev->pers->owner);
	/* Invalidate devices that are now superfluous */
	list_for_each_entry(rdev, &mddev->disks, same_set)
+26 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@
#include <linux/cpu.h>
#include "md.h"
#include "raid5.h"
#include "raid0.h"
#include "bitmap.h"

/*
@@ -5619,6 +5620,21 @@ static void raid5_quiesce(mddev_t *mddev, int state)
}


static void *raid5_takeover_raid0(mddev_t *mddev)
{

	mddev->new_level = 5;
	mddev->new_layout = ALGORITHM_PARITY_N;
	mddev->new_chunk_sectors = mddev->chunk_sectors;
	mddev->raid_disks += 1;
	mddev->delta_disks = 1;
	/* make sure it will be not marked as dirty */
	mddev->recovery_cp = MaxSector;

	return setup_conf(mddev);
}


static void *raid5_takeover_raid1(mddev_t *mddev)
{
	int chunksect;
@@ -5748,6 +5764,16 @@ static void *raid5_takeover(mddev_t *mddev)
	 *  raid4 - trivial - just use a raid4 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 == 1)
		return raid5_takeover_raid1(mddev);