/*
 * Copyright (C) 2010-2011 Neil Brown
 * Copyright (C) 2010-2016 Red Hat, Inc. All rights reserved.
 *
 * This file is released under the GPL.
 */

#include <linux/slab.h>
#include <linux/module.h>

#include "md.h"
#include "raid1.h"
#include "raid5.h"
#include "raid10.h"
#include "bitmap.h"

#include <linux/device-mapper.h>

#define DM_MSG_PREFIX "raid"
#define	MAX_RAID_DEVICES	253 /* md-raid kernel limit */

/*
 * Minimum sectors of free reshape space per raid device
 */
#define	MIN_FREE_RESHAPE_SPACE to_sector(4*4096)

static bool devices_handle_discard_safely = false;

/*
 * The following flags are used by dm-raid.c to set up the array state.
 * They must be cleared before md_run is called.
 */
#define FirstUse 10		/* rdev flag */

struct raid_dev {
	/*
	 * Two DM devices, one to hold metadata and one to hold the
	 * actual data/parity.	The reason for this is to not confuse
	 * ti->len and give more flexibility in altering size and
	 * characteristics.
	 *
	 * While it is possible for this device to be associated
	 * with a different physical device than the data_dev, it
	 * is intended for it to be the same.
	 *    |--------- Physical Device ---------|
	 *    |- meta_dev -|------ data_dev ------|
	 */
	struct dm_dev *meta_dev;
	struct dm_dev *data_dev;
	struct md_rdev rdev;
};

/*
 * Bits for establishing rs->ctr_flags
 *
 * 1 = no flag value
 * 2 = flag with value
 */
#define __CTR_FLAG_SYNC			0  /* 1 */ /* Not with raid0! */
#define __CTR_FLAG_NOSYNC		1  /* 1 */ /* Not with raid0! */
#define __CTR_FLAG_REBUILD		2  /* 2 */ /* Not with raid0! */
#define __CTR_FLAG_DAEMON_SLEEP		3  /* 2 */ /* Not with raid0! */
#define __CTR_FLAG_MIN_RECOVERY_RATE	4  /* 2 */ /* Not with raid0! */
#define __CTR_FLAG_MAX_RECOVERY_RATE	5  /* 2 */ /* Not with raid0! */
#define __CTR_FLAG_MAX_WRITE_BEHIND	6  /* 2 */ /* Only with raid1! */
#define __CTR_FLAG_WRITE_MOSTLY		7  /* 2 */ /* Only with raid1! */
#define __CTR_FLAG_STRIPE_CACHE		8  /* 2 */ /* Only with raid4/5/6! */
#define __CTR_FLAG_REGION_SIZE		9  /* 2 */ /* Not with raid0! */
#define __CTR_FLAG_RAID10_COPIES	10 /* 2 */ /* Only with raid10 */
#define __CTR_FLAG_RAID10_FORMAT	11 /* 2 */ /* Only with raid10 */
/* New for v1.9.0 */
#define __CTR_FLAG_DELTA_DISKS		12 /* 2 */ /* Only with reshapable raid4/5/6/10! */
#define __CTR_FLAG_DATA_OFFSET		13 /* 2 */ /* Only with reshapable raid4/5/6/10! */
#define __CTR_FLAG_RAID10_USE_NEAR_SETS 14 /* 2 */ /* Only with raid10! */

/*
 * Flags for rs->ctr_flags field.
 */
#define CTR_FLAG_SYNC			(1 << __CTR_FLAG_SYNC)
#define CTR_FLAG_NOSYNC			(1 << __CTR_FLAG_NOSYNC)
#define CTR_FLAG_REBUILD		(1 << __CTR_FLAG_REBUILD)
#define CTR_FLAG_DAEMON_SLEEP		(1 << __CTR_FLAG_DAEMON_SLEEP)
#define CTR_FLAG_MIN_RECOVERY_RATE	(1 << __CTR_FLAG_MIN_RECOVERY_RATE)
#define CTR_FLAG_MAX_RECOVERY_RATE	(1 << __CTR_FLAG_MAX_RECOVERY_RATE)
#define CTR_FLAG_MAX_WRITE_BEHIND	(1 << __CTR_FLAG_MAX_WRITE_BEHIND)
#define CTR_FLAG_WRITE_MOSTLY		(1 << __CTR_FLAG_WRITE_MOSTLY)
#define CTR_FLAG_STRIPE_CACHE		(1 << __CTR_FLAG_STRIPE_CACHE)
#define CTR_FLAG_REGION_SIZE		(1 << __CTR_FLAG_REGION_SIZE)
#define CTR_FLAG_RAID10_COPIES		(1 << __CTR_FLAG_RAID10_COPIES)
#define CTR_FLAG_RAID10_FORMAT		(1 << __CTR_FLAG_RAID10_FORMAT)
#define CTR_FLAG_DELTA_DISKS		(1 << __CTR_FLAG_DELTA_DISKS)
#define CTR_FLAG_DATA_OFFSET		(1 << __CTR_FLAG_DATA_OFFSET)
#define CTR_FLAG_RAID10_USE_NEAR_SETS	(1 << __CTR_FLAG_RAID10_USE_NEAR_SETS)

/*
 * Definitions of various constructor flags to
 * be used in checks of valid / invalid flags
 * per raid level.
 */
/* Define all any sync flags */
#define	CTR_FLAGS_ANY_SYNC		(CTR_FLAG_SYNC | CTR_FLAG_NOSYNC)

/* Define flags for options without argument (e.g. 'nosync') */
#define	CTR_FLAG_OPTIONS_NO_ARGS	(CTR_FLAGS_ANY_SYNC | \
					 CTR_FLAG_RAID10_USE_NEAR_SETS)

/* Define flags for options with one argument (e.g. 'delta_disks +2') */
#define CTR_FLAG_OPTIONS_ONE_ARG (CTR_FLAG_REBUILD | \
				  CTR_FLAG_WRITE_MOSTLY | \
				  CTR_FLAG_DAEMON_SLEEP | \
				  CTR_FLAG_MIN_RECOVERY_RATE | \
				  CTR_FLAG_MAX_RECOVERY_RATE | \
				  CTR_FLAG_MAX_WRITE_BEHIND | \
				  CTR_FLAG_STRIPE_CACHE | \
				  CTR_FLAG_REGION_SIZE | \
				  CTR_FLAG_RAID10_COPIES | \
				  CTR_FLAG_RAID10_FORMAT | \
				  CTR_FLAG_DELTA_DISKS | \
				  CTR_FLAG_DATA_OFFSET)

/* Valid options definitions per raid level... */

/* "raid0" does only accept data offset */
#define RAID0_VALID_FLAGS	(CTR_FLAG_DATA_OFFSET)

/* "raid1" does not accept stripe cache, data offset, delta_disks or any raid10 options */
#define RAID1_VALID_FLAGS	(CTR_FLAGS_ANY_SYNC | \
				 CTR_FLAG_REBUILD | \
				 CTR_FLAG_WRITE_MOSTLY | \
				 CTR_FLAG_DAEMON_SLEEP | \
				 CTR_FLAG_MIN_RECOVERY_RATE | \
				 CTR_FLAG_MAX_RECOVERY_RATE | \
				 CTR_FLAG_MAX_WRITE_BEHIND | \
				 CTR_FLAG_REGION_SIZE | \
				 CTR_FLAG_DATA_OFFSET)

/* "raid10" does not accept any raid1 or stripe cache options */
#define RAID10_VALID_FLAGS	(CTR_FLAGS_ANY_SYNC | \
				 CTR_FLAG_REBUILD | \
				 CTR_FLAG_DAEMON_SLEEP | \
				 CTR_FLAG_MIN_RECOVERY_RATE | \
				 CTR_FLAG_MAX_RECOVERY_RATE | \
				 CTR_FLAG_REGION_SIZE | \
				 CTR_FLAG_RAID10_COPIES | \
				 CTR_FLAG_RAID10_FORMAT | \
				 CTR_FLAG_DELTA_DISKS | \
				 CTR_FLAG_DATA_OFFSET | \
				 CTR_FLAG_RAID10_USE_NEAR_SETS)

/*
 * "raid4/5/6" do not accept any raid1 or raid10 specific options
 *
 * "raid6" does not accept "nosync", because it is not guaranteed
 * that both parity and q-syndrome are being written properly with
 * any writes
 */
#define RAID45_VALID_FLAGS	(CTR_FLAGS_ANY_SYNC | \
				 CTR_FLAG_REBUILD | \
				 CTR_FLAG_DAEMON_SLEEP | \
				 CTR_FLAG_MIN_RECOVERY_RATE | \
				 CTR_FLAG_MAX_RECOVERY_RATE | \
				 CTR_FLAG_MAX_WRITE_BEHIND | \
				 CTR_FLAG_STRIPE_CACHE | \
				 CTR_FLAG_REGION_SIZE | \
				 CTR_FLAG_DELTA_DISKS | \
				 CTR_FLAG_DATA_OFFSET)

#define RAID6_VALID_FLAGS	(CTR_FLAG_SYNC | \
				 CTR_FLAG_REBUILD | \
				 CTR_FLAG_DAEMON_SLEEP | \
				 CTR_FLAG_MIN_RECOVERY_RATE | \
				 CTR_FLAG_MAX_RECOVERY_RATE | \
				 CTR_FLAG_MAX_WRITE_BEHIND | \
				 CTR_FLAG_STRIPE_CACHE | \
				 CTR_FLAG_REGION_SIZE | \
				 CTR_FLAG_DELTA_DISKS | \
				 CTR_FLAG_DATA_OFFSET)
/* ...valid options definitions per raid level */

/*
 * Flags for rs->runtime_flags field
 * (RT_FLAG prefix meaning "runtime flag")
 *
 * These are all internal and used to define runtime state,
 * e.g. to prevent another resume from preresume processing
 * the raid set all over again.
 */
#define RT_FLAG_RS_PRERESUMED		0
#define RT_FLAG_RS_RESUMED		1
#define RT_FLAG_RS_BITMAP_LOADED	2
#define RT_FLAG_UPDATE_SBS		3
#define RT_FLAG_RESHAPE_RS		4
#define RT_FLAG_KEEP_RS_FROZEN		5

/* Array elements of 64 bit needed for rebuild/write_mostly bits */
#define DISKS_ARRAY_ELEMS ((MAX_RAID_DEVICES + (sizeof(uint64_t) * 8 - 1)) / sizeof(uint64_t) / 8)

/*
 * raid set level, layout and chunk sectors backup/restore
 */
struct rs_layout {
	int new_level;
	int new_layout;
	int new_chunk_sectors;
};

struct raid_set {
	struct dm_target *ti;

	uint32_t bitmap_loaded;
	uint32_t stripe_cache_entries;
	unsigned long ctr_flags;
	unsigned long runtime_flags;

	uint64_t rebuild_disks[DISKS_ARRAY_ELEMS];

	int raid_disks;
	int delta_disks;
	int data_offset;
	int raid10_copies;
	int requested_bitmap_chunk_sectors;

	struct mddev md;
	struct raid_type *raid_type;
	struct dm_target_callbacks callbacks;

	struct raid_dev dev[0];
};

static void rs_config_backup(struct raid_set *rs, struct rs_layout *l)
{
	struct mddev *mddev = &rs->md;

	l->new_level = mddev->new_level;
	l->new_layout = mddev->new_layout;
	l->new_chunk_sectors = mddev->new_chunk_sectors;
}

static void rs_config_restore(struct raid_set *rs, struct rs_layout *l)
{
	struct mddev *mddev = &rs->md;

	mddev->new_level = l->new_level;
	mddev->new_layout = l->new_layout;
	mddev->new_chunk_sectors = l->new_chunk_sectors;
}

/* raid10 algorithms (i.e. formats) */
#define	ALGORITHM_RAID10_DEFAULT	0
#define	ALGORITHM_RAID10_NEAR		1
#define	ALGORITHM_RAID10_OFFSET		2
#define	ALGORITHM_RAID10_FAR		3

/* Supported raid types and properties. */
static struct raid_type {
	const char *name;		/* RAID algorithm. */
	const char *descr;		/* Descriptor text for logging. */
	const unsigned parity_devs;	/* # of parity devices. */
	const unsigned minimal_devs;	/* minimal # of devices in set. */
	const unsigned level;		/* RAID level. */
	const unsigned algorithm;	/* RAID algorithm. */
} raid_types[] = {
	{"raid0",	  "raid0 (striping)",			    0, 2, 0,  0 /* NONE */},
	{"raid1",	  "raid1 (mirroring)",			    0, 2, 1,  0 /* NONE */},
	{"raid10_far",	  "raid10 far (striped mirrors)",	    0, 2, 10, ALGORITHM_RAID10_FAR},
	{"raid10_offset", "raid10 offset (striped mirrors)",	    0, 2, 10, ALGORITHM_RAID10_OFFSET},
	{"raid10_near",	  "raid10 near (striped mirrors)",	    0, 2, 10, ALGORITHM_RAID10_NEAR},
	{"raid10",	  "raid10 (striped mirrors)",		    0, 2, 10, ALGORITHM_RAID10_DEFAULT},
	{"raid4",	  "raid4 (dedicated last parity disk)",	    1, 2, 4,  ALGORITHM_PARITY_N}, /* raid4 layout = raid5_n */
	{"raid5_n",	  "raid5 (dedicated last parity disk)",	    1, 2, 5,  ALGORITHM_PARITY_N},
	{"raid5_ls",	  "raid5 (left symmetric)",		    1, 2, 5,  ALGORITHM_LEFT_SYMMETRIC},
	{"raid5_rs",	  "raid5 (right symmetric)",		    1, 2, 5,  ALGORITHM_RIGHT_SYMMETRIC},
	{"raid5_la",	  "raid5 (left asymmetric)",		    1, 2, 5,  ALGORITHM_LEFT_ASYMMETRIC},
	{"raid5_ra",	  "raid5 (right asymmetric)",		    1, 2, 5,  ALGORITHM_RIGHT_ASYMMETRIC},
	{"raid6_zr",	  "raid6 (zero restart)",		    2, 4, 6,  ALGORITHM_ROTATING_ZERO_RESTART},
	{"raid6_nr",	  "raid6 (N restart)",			    2, 4, 6,  ALGORITHM_ROTATING_N_RESTART},
	{"raid6_nc",	  "raid6 (N continue)",			    2, 4, 6,  ALGORITHM_ROTATING_N_CONTINUE},
	{"raid6_n_6",	  "raid6 (dedicated parity/Q n/6)",	    2, 4, 6,  ALGORITHM_PARITY_N_6},
	{"raid6_ls_6",	  "raid6 (left symmetric dedicated Q 6)",   2, 4, 6,  ALGORITHM_LEFT_SYMMETRIC_6},
	{"raid6_rs_6",	  "raid6 (right symmetric dedicated Q 6)",  2, 4, 6,  ALGORITHM_RIGHT_SYMMETRIC_6},
	{"raid6_la_6",	  "raid6 (left asymmetric dedicated Q 6)",  2, 4, 6,  ALGORITHM_LEFT_ASYMMETRIC_6},
	{"raid6_ra_6",	  "raid6 (right asymmetric dedicated Q 6)", 2, 4, 6,  ALGORITHM_RIGHT_ASYMMETRIC_6}
};

/* True, if @v is in inclusive range [@min, @max] */
static bool __within_range(long v, long min, long max)
{
	return v >= min && v <= max;
}

/* All table line arguments are defined here */
static struct arg_name_flag {
	const unsigned long flag;
	const char *name;
} __arg_name_flags[] = {
	{ CTR_FLAG_SYNC, "sync"},
	{ CTR_FLAG_NOSYNC, "nosync"},
	{ CTR_FLAG_REBUILD, "rebuild"},
	{ CTR_FLAG_DAEMON_SLEEP, "daemon_sleep"},
	{ CTR_FLAG_MIN_RECOVERY_RATE, "min_recovery_rate"},
	{ CTR_FLAG_MAX_RECOVERY_RATE, "max_recovery_rate"},
	{ CTR_FLAG_MAX_WRITE_BEHIND, "max_write_behind"},
	{ CTR_FLAG_WRITE_MOSTLY, "writemostly"},
	{ CTR_FLAG_STRIPE_CACHE, "stripe_cache"},
	{ CTR_FLAG_REGION_SIZE, "region_size"},
	{ CTR_FLAG_RAID10_COPIES, "raid10_copies"},
	{ CTR_FLAG_RAID10_FORMAT, "raid10_format"},
	{ CTR_FLAG_DATA_OFFSET, "data_offset"},
	{ CTR_FLAG_DELTA_DISKS, "delta_disks"},
	{ CTR_FLAG_RAID10_USE_NEAR_SETS, "raid10_use_near_sets"},
};

/* Return argument name string for given @flag */
static const char *dm_raid_arg_name_by_flag(const uint32_t flag)
{
	if (hweight32(flag) == 1) {
		struct arg_name_flag *anf = __arg_name_flags + ARRAY_SIZE(__arg_name_flags);

		while (anf-- > __arg_name_flags)
			if (flag & anf->flag)
				return anf->name;

	} else
		DMERR("%s called with more than one flag!", __func__);

	return NULL;
}

/*
 * bool helpers to test for various raid levels of a raid set,
 * is. it's level as reported by the superblock rather than
 * the requested raid_type passed to the constructor.
 */
/* Return true, if raid set in @rs is raid0 */
static bool rs_is_raid0(struct raid_set *rs)
{
	return !rs->md.level;
}

/* Return true, if raid set in @rs is raid1 */
static bool rs_is_raid1(struct raid_set *rs)
{
	return rs->md.level == 1;
}

/* Return true, if raid set in @rs is raid10 */
static bool rs_is_raid10(struct raid_set *rs)
{
	return rs->md.level == 10;
}

/* Return true, if raid set in @rs is level 4, 5 or 6 */
static bool rs_is_raid456(struct raid_set *rs)
{
	return __within_range(rs->md.level, 4, 6);
}

/* Return true, if raid set in @rs is reshapable */
static unsigned int __is_raid10_far(int layout);
static bool rs_is_reshapable(struct raid_set *rs)
{
	return rs_is_raid456(rs) ||
	       (rs_is_raid10(rs) && !__is_raid10_far(rs->md.new_layout));
}

/* Return true, if raid set in @rs is recovering */
static bool rs_is_recovering(struct raid_set *rs)
{
	smp_rmb();
	return rs->md.recovery_cp != MaxSector;
}

/* Return true, if raid set in @rs is reshaping */
static bool rs_is_reshaping(struct raid_set *rs)
{
	smp_rmb();
	return rs->md.reshape_position != MaxSector;
}

/*
 * bool helpers to test for various raid levels of a raid type
 */

/* Return true, if raid type in @rt is raid0 */
static bool rt_is_raid0(struct raid_type *rt)
{
	return !rt->level;
}

/* Return true, if raid type in @rt is raid1 */
static bool rt_is_raid1(struct raid_type *rt)
{
	return rt->level == 1;
}

/* Return true, if raid type in @rt is raid10 */
static bool rt_is_raid10(struct raid_type *rt)
{
	return rt->level == 10;
}

/* Return true, if raid type in @rt is raid4/5 */
static bool rt_is_raid45(struct raid_type *rt)
{
	return __within_range(rt->level, 4, 5);
}

/* Return true, if raid type in @rt is raid6 */
static bool rt_is_raid6(struct raid_type *rt)
{
	return rt->level == 6;
}

/* Return true, if raid type in @rt is raid4/5/6 */
static bool rt_is_raid456(struct raid_type *rt)
{
	return __within_range(rt->level, 4, 6);
}
/* END: raid level bools */

/* Return valid ctr flags for the raid level of @rs */
static unsigned long __valid_flags(struct raid_set *rs)
{
	if (rt_is_raid0(rs->raid_type))
		return RAID0_VALID_FLAGS;
	else if (rt_is_raid1(rs->raid_type))
		return RAID1_VALID_FLAGS;
	else if (rt_is_raid10(rs->raid_type))
		return RAID10_VALID_FLAGS;
	else if (rt_is_raid45(rs->raid_type))
		return RAID45_VALID_FLAGS;
	else if (rt_is_raid6(rs->raid_type))
		return RAID6_VALID_FLAGS;

	return ~0;
}

/*
 * Check for valid flags set on @rs
 *
 * Has to be called after parsing of the ctr flags!
 */
static int rs_check_for_valid_flags(struct raid_set *rs)
{
	if (rs->ctr_flags & ~__valid_flags(rs)) {
		rs->ti->error = "Invalid flags combination";
		return -EINVAL;
	}

	return 0;
}

/* MD raid10 bit definitions and helpers */
#define RAID10_OFFSET			(1 << 16) /* stripes with data copies area adjacent on devices */
#define RAID10_BROCKEN_USE_FAR_SETS	(1 << 17) /* Broken in raid10.c: use sets instead of whole stripe rotation */
#define RAID10_USE_FAR_SETS		(1 << 18) /* Use sets instead of whole stripe rotation */
#define RAID10_FAR_COPIES_SHIFT		8	  /* raid10 # far copies shift (2nd byte of layout) */

/* Return md raid10 near copies for @layout */
static unsigned int __raid10_near_copies(int layout)
{
	return layout & 0xFF;
}

/* Return md raid10 far copies for @layout */
static unsigned int __raid10_far_copies(int layout)
{
	return __raid10_near_copies(layout >> RAID10_FAR_COPIES_SHIFT);
}

/* Return true if md raid10 offset for @layout */
static unsigned int __is_raid10_offset(int layout)
{
	return layout & RAID10_OFFSET;
}

/* Return true if md raid10 near for @layout */
static unsigned int __is_raid10_near(int layout)
{
	return !__is_raid10_offset(layout) && __raid10_near_copies(layout) > 1;
}

/* Return true if md raid10 far for @layout */
static unsigned int __is_raid10_far(int layout)
{
	return !__is_raid10_offset(layout) && __raid10_far_copies(layout) > 1;
}

/* Return md raid10 layout string for @layout */
static const char *raid10_md_layout_to_format(int layout)
{
	/*
	 * Bit 16 stands for "offset"
	 * (i.e. adjacent stripes hold copies)
	 *
	 * Refer to MD's raid10.c for details
	 */
	if (__is_raid10_offset(layout))
		return "offset";

	if (__raid10_near_copies(layout) > 1)
		return "near";

	WARN_ON(__raid10_far_copies(layout) < 2);

	return "far";
}

/* Return md raid10 algorithm for @name */
static int raid10_name_to_format(const char *name)
{
	if (!strcasecmp(name, "near"))
		return ALGORITHM_RAID10_NEAR;
	else if (!strcasecmp(name, "offset"))
		return ALGORITHM_RAID10_OFFSET;
	else if (!strcasecmp(name, "far"))
		return ALGORITHM_RAID10_FAR;

	return -EINVAL;
}

/* Return md raid10 copies for @layout */
static unsigned int raid10_md_layout_to_copies(int layout)
{
	return __raid10_near_copies(layout) > 1 ?
		__raid10_near_copies(layout) : __raid10_far_copies(layout);
}

/* Return md raid10 format id for @format string */
static int raid10_format_to_md_layout(struct raid_set *rs,
				      unsigned int algorithm,
				      unsigned int copies)
{
	unsigned int n = 1, f = 1, r = 0;

	/*
	 * MD resilienece flaw:
	 *
	 * enabling use_far_sets for far/offset formats causes copies
	 * to be colocated on the same devs together with their origins!
	 *
	 * -> disable it for now in the definition above
	 */
	if (algorithm == ALGORITHM_RAID10_DEFAULT ||
	    algorithm == ALGORITHM_RAID10_NEAR)
		n = copies;

	else if (algorithm == ALGORITHM_RAID10_OFFSET) {
		f = copies;
		r = RAID10_OFFSET;
		if (!test_bit(__CTR_FLAG_RAID10_USE_NEAR_SETS, &rs->ctr_flags))
			r |= RAID10_USE_FAR_SETS;

	} else if (algorithm == ALGORITHM_RAID10_FAR) {
		f = copies;
		r = !RAID10_OFFSET;
		if (!test_bit(__CTR_FLAG_RAID10_USE_NEAR_SETS, &rs->ctr_flags))
			r |= RAID10_USE_FAR_SETS;

	} else
		return -EINVAL;

	return r | (f << RAID10_FAR_COPIES_SHIFT) | n;
}
/* END: MD raid10 bit definitions and helpers */

/* Check for any of the raid10 algorithms */
static int __got_raid10(struct raid_type *rtp, const int layout)
{
	if (rtp->level == 10) {
		switch (rtp->algorithm) {
		case ALGORITHM_RAID10_DEFAULT:
		case ALGORITHM_RAID10_NEAR:
			return __is_raid10_near(layout);
		case ALGORITHM_RAID10_OFFSET:
			return __is_raid10_offset(layout);
		case ALGORITHM_RAID10_FAR:
			return __is_raid10_far(layout);
		default:
			break;
		}
	}

	return 0;
}

/* Return raid_type for @name */
static struct raid_type *get_raid_type(const char *name)
{
	struct raid_type *rtp = raid_types + ARRAY_SIZE(raid_types);

	while (rtp-- > raid_types)
		if (!strcasecmp(rtp->name, name))
			return rtp;

	return NULL;
}

/* Return raid_type for @name based derived from @level and @layout */
static struct raid_type *get_raid_type_by_ll(const int level, const int layout)
{
	struct raid_type *rtp = raid_types + ARRAY_SIZE(raid_types);

	while (rtp-- > raid_types) {
		/* RAID10 special checks based on @layout flags/properties */
		if (rtp->level == level &&
		    (__got_raid10(rtp, layout) || rtp->algorithm == layout))
			return rtp;
	}

	return NULL;
}

/*
 * Conditionally change bdev capacity of @rs
 * in case of a disk add/remove reshape
 */
static void rs_set_capacity(struct raid_set *rs)
{
	struct mddev *mddev = &rs->md;

	/* Make sure we access most actual mddev properties */
	smp_rmb();
	if (rs->ti->len != mddev->array_sectors && !rs_is_reshaping(rs)) {
		struct gendisk *gendisk = dm_disk(dm_table_get_md(rs->ti->table));

		set_capacity(gendisk, mddev->array_sectors);
		revalidate_disk(gendisk);
	}
}

/*
 * Set the mddev properties in @rs to the current
 * ones retrieved from the freshest superblock
 */
static void rs_set_cur(struct raid_set *rs)
{
	struct mddev *mddev = &rs->md;

	mddev->new_level = mddev->level;
	mddev->new_layout = mddev->layout;
	mddev->new_chunk_sectors = mddev->chunk_sectors;
}

/*
 * Set the mddev properties in @rs to the new
 * ones requested by the ctr
 */
static void rs_set_new(struct raid_set *rs)
{
	struct mddev *mddev = &rs->md;

	mddev->level = mddev->new_level;
	mddev->layout = mddev->new_layout;
	mddev->chunk_sectors = mddev->new_chunk_sectors;
	mddev->raid_disks = rs->raid_disks;
	mddev->delta_disks = 0;
}

static struct raid_set *raid_set_alloc(struct dm_target *ti, struct raid_type *raid_type,
				       unsigned raid_devs)
{
	unsigned i;
	struct raid_set *rs;

	if (raid_devs <= raid_type->parity_devs) {
		ti->error = "Insufficient number of devices";
		return ERR_PTR(-EINVAL);
	}

	rs = kzalloc(sizeof(*rs) + raid_devs * sizeof(rs->dev[0]), GFP_KERNEL);
	if (!rs) {
		ti->error = "Cannot allocate raid context";
		return ERR_PTR(-ENOMEM);
	}

	mddev_init(&rs->md);

	rs->raid_disks = raid_devs;
	rs->delta_disks = 0;

	rs->ti = ti;
	rs->raid_type = raid_type;
	rs->stripe_cache_entries = 256;
	rs->md.raid_disks = raid_devs;
	rs->md.level = raid_type->level;
	rs->md.new_level = rs->md.level;
	rs->md.layout = raid_type->algorithm;
	rs->md.new_layout = rs->md.layout;
	rs->md.delta_disks = 0;
	rs->md.recovery_cp = rs_is_raid0(rs) ? MaxSector : 0;

	for (i = 0; i < raid_devs; i++)
		md_rdev_init(&rs->dev[i].rdev);

	/*
	 * Remaining items to be initialized by further RAID params:
	 *  rs->md.persistent
	 *  rs->md.external
	 *  rs->md.chunk_sectors
	 *  rs->md.new_chunk_sectors
	 *  rs->md.dev_sectors
	 */

	return rs;
}

static void raid_set_free(struct raid_set *rs)
{
	int i;

	for (i = 0; i < rs->md.raid_disks; i++) {
		if (rs->dev[i].meta_dev)
			dm_put_device(rs->ti, rs->dev[i].meta_dev);
		md_rdev_clear(&rs->dev[i].rdev);
		if (rs->dev[i].data_dev)
			dm_put_device(rs->ti, rs->dev[i].data_dev);
	}

	kfree(rs);
}

/*
 * For every device we have two words
 *  <meta_dev>: meta device name or '-' if missing
 *  <data_dev>: data device name or '-' if missing
 *
 * The following are permitted:
 *    - -
 *    - <data_dev>
 *    <meta_dev> <data_dev>
 *
 * The following is not allowed:
 *    <meta_dev> -
 *
 * This code parses those words.  If there is a failure,
 * the caller must use raid_set_free() to unwind the operations.
 */
static int parse_dev_params(struct raid_set *rs, struct dm_arg_set *as)
{
	int i;
	int rebuild = 0;
	int metadata_available = 0;
	int r = 0;
	const char *arg;

	/* Put off the number of raid devices argument to get to dev pairs */
	arg = dm_shift_arg(as);
	if (!arg)
		return -EINVAL;

	for (i = 0; i < rs->md.raid_disks; i++) {
		rs->dev[i].rdev.raid_disk = i;

		rs->dev[i].meta_dev = NULL;
		rs->dev[i].data_dev = NULL;

		/*
		 * There are no offsets, since there is a separate device
		 * for data and metadata.
		 */
		rs->dev[i].rdev.data_offset = 0;
		rs->dev[i].rdev.mddev = &rs->md;

		arg = dm_shift_arg(as);
		if (!arg)
			return -EINVAL;

		if (strcmp(arg, "-")) {
			r = dm_get_device(rs->ti, arg, dm_table_get_mode(rs->ti->table),
					  &rs->dev[i].meta_dev);
			if (r) {
				rs->ti->error = "RAID metadata device lookup failure";
				return r;
			}

			rs->dev[i].rdev.sb_page = alloc_page(GFP_KERNEL);
			if (!rs->dev[i].rdev.sb_page) {
				rs->ti->error = "Failed to allocate superblock page";
				return -ENOMEM;
			}
		}

		arg = dm_shift_arg(as);
		if (!arg)
			return -EINVAL;

		if (!strcmp(arg, "-")) {
			if (!test_bit(In_sync, &rs->dev[i].rdev.flags) &&
			    (!rs->dev[i].rdev.recovery_offset)) {
				rs->ti->error = "Drive designated for rebuild not specified";
				return -EINVAL;
			}

			if (rs->dev[i].meta_dev) {
				rs->ti->error = "No data device supplied with metadata device";
				return -EINVAL;
			}

			continue;
		}

		r = dm_get_device(rs->ti, arg, dm_table_get_mode(rs->ti->table),
				  &rs->dev[i].data_dev);
		if (r) {
			rs->ti->error = "RAID device lookup failure";
			return r;
		}

		if (rs->dev[i].meta_dev) {
			metadata_available = 1;
			rs->dev[i].rdev.meta_bdev = rs->dev[i].meta_dev->bdev;
		}
		rs->dev[i].rdev.bdev = rs->dev[i].data_dev->bdev;
		list_add_tail(&rs->dev[i].rdev.same_set, &rs->md.disks);
		if (!test_bit(In_sync, &rs->dev[i].rdev.flags))
			rebuild++;
	}

	if (metadata_available) {
		rs->md.external = 0;
		rs->md.persistent = 1;
		rs->md.major_version = 2;
	} else if (rebuild && !rs->md.recovery_cp) {
		/*
		 * Without metadata, we will not be able to tell if the array
		 * is in-sync or not - we must assume it is not.  Therefore,
		 * it is impossible to rebuild a drive.
		 *
		 * Even if there is metadata, the on-disk information may
		 * indicate that the array is not in-sync and it will then
		 * fail at that time.
		 *
		 * User could specify 'nosync' option if desperate.
		 */
		rs->ti->error = "Unable to rebuild drive while array is not in-sync";
		return -EINVAL;
	}

	return 0;
}

/*
 * validate_region_size
 * @rs
 * @region_size:  region size in sectors.  If 0, pick a size (4MiB default).
 *
 * Set rs->md.bitmap_info.chunksize (which really refers to 'region size').
 * Ensure that (ti->len/region_size < 2^21) - required by MD bitmap.
 *
 * Returns: 0 on success, -EINVAL on failure.
 */
static int validate_region_size(struct raid_set *rs, unsigned long region_size)
{
	unsigned long min_region_size = rs->ti->len / (1 << 21);

	if (!region_size) {
		/*
		 * Choose a reasonable default.	 All figures in sectors.
		 */
		if (min_region_size > (1 << 13)) {
			/* If not a power of 2, make it the next power of 2 */
			region_size = roundup_pow_of_two(min_region_size);
			DMINFO("Choosing default region size of %lu sectors",
			       region_size);
		} else {
			DMINFO("Choosing default region size of 4MiB");
			region_size = 1 << 13; /* sectors */
		}
	} else {
		/*
		 * Validate user-supplied value.
		 */
		if (region_size > rs->ti->len) {
			rs->ti->error = "Supplied region size is too large";
			return -EINVAL;
		}

		if (region_size < min_region_size) {
			DMERR("Supplied region_size (%lu sectors) below minimum (%lu)",
			      region_size, min_region_size);
			rs->ti->error = "Supplied region size is too small";
			return -EINVAL;
		}

		if (!is_power_of_2(region_size)) {
			rs->ti->error = "Region size is not a power of 2";
			return -EINVAL;
		}

		if (region_size < rs->md.chunk_sectors) {
			rs->ti->error = "Region size is smaller than the chunk size";
			return -EINVAL;
		}
	}

	/*
	 * Convert sectors to bytes.
	 */
	rs->md.bitmap_info.chunksize = (region_size << 9);

	return 0;
}

/*
 * validate_raid_redundancy
 * @rs
 *
 * Determine if there are enough devices in the array that haven't
 * failed (or are being rebuilt) to form a usable array.
 *
 * Returns: 0 on success, -EINVAL on failure.
 */
static int validate_raid_redundancy(struct raid_set *rs)
{
	unsigned i, rebuild_cnt = 0;
	unsigned rebuilds_per_group = 0, copies;
	unsigned group_size, last_group_start;

	for (i = 0; i < rs->md.raid_disks; i++)
		if (!test_bit(In_sync, &rs->dev[i].rdev.flags) ||
		    !rs->dev[i].rdev.sb_page)
			rebuild_cnt++;

	switch (rs->raid_type->level) {
	case 1:
		if (rebuild_cnt >= rs->md.raid_disks)
			goto too_many;
		break;
	case 4:
	case 5:
	case 6:
		if (rebuild_cnt > rs->raid_type->parity_devs)
			goto too_many;
		break;
	case 10:
		copies = raid10_md_layout_to_copies(rs->md.new_layout);
		if (rebuild_cnt < copies)
			break;

		/*
		 * It is possible to have a higher rebuild count for RAID10,
		 * as long as the failed devices occur in different mirror
		 * groups (i.e. different stripes).
		 *
		 * When checking "near" format, make sure no adjacent devices
		 * have failed beyond what can be handled.  In addition to the
		 * simple case where the number of devices is a multiple of the
		 * number of copies, we must also handle cases where the number
		 * of devices is not a multiple of the number of copies.
		 * E.g.	   dev1 dev2 dev3 dev4 dev5
		 *	    A	 A    B	   B	C
		 *	    C	 D    D	   E	E
		 */
		if (__is_raid10_near(rs->md.new_layout)) {
			for (i = 0; i < rs->raid_disks; i++) {
				if (!(i % copies))
					rebuilds_per_group = 0;
				if ((!rs->dev[i].rdev.sb_page ||
				    !test_bit(In_sync, &rs->dev[i].rdev.flags)) &&
				    (++rebuilds_per_group >= copies))
					goto too_many;
			}
			break;
		}

		/*
		 * When checking "far" and "offset" formats, we need to ensure
		 * that the device that holds its copy is not also dead or
		 * being rebuilt.  (Note that "far" and "offset" formats only
		 * support two copies right now.  These formats also only ever
		 * use the 'use_far_sets' variant.)
		 *
		 * This check is somewhat complicated by the need to account
		 * for arrays that are not a multiple of (far) copies.	This
		 * results in the need to treat the last (potentially larger)
		 * set differently.
		 */
		group_size = (rs->md.raid_disks / copies);
		last_group_start = (rs->md.raid_disks / group_size) - 1;
		last_group_start *= group_size;
		for (i = 0; i < rs->md.raid_disks; i++) {
			if (!(i % copies) && !(i > last_group_start))
				rebuilds_per_group = 0;
			if ((!rs->dev[i].rdev.sb_page ||
			     !test_bit(In_sync, &rs->dev[i].rdev.flags)) &&
			    (++rebuilds_per_group >= copies))
					goto too_many;
		}
		break;
	default:
		if (rebuild_cnt)
			return -EINVAL;
	}

	return 0;

too_many:
	return -EINVAL;
}

/*
 * Possible arguments are...
 *	<chunk_size> [optional_args]
 *
 * Argument definitions
 *    <chunk_size>			The number of sectors per disk that
 *					will form the "stripe"
 *    [[no]sync]			Force or prevent recovery of the
 *					entire array
 *    [rebuild <idx>]			Rebuild the drive indicated by the index
 *    [daemon_sleep <ms>]		Time between bitmap daemon work to
 *					clear bits
 *    [min_recovery_rate <kB/sec/disk>]	Throttle RAID initialization
 *    [max_recovery_rate <kB/sec/disk>]	Throttle RAID initialization
 *    [write_mostly <idx>]		Indicate a write mostly drive via index
 *    [max_write_behind <sectors>]	See '-write-behind=' (man mdadm)
 *    [stripe_cache <sectors>]		Stripe cache size for higher RAIDs
 *    [region_size <sectors>]		Defines granularity of bitmap
 *
 * RAID10-only options:
 *    [raid10_copies <# copies>]	Number of copies.  (Default: 2)
 *    [raid10_format <near|far|offset>] Layout algorithm.  (Default: near)
 */
static int parse_raid_params(struct raid_set *rs, struct dm_arg_set *as,
			     unsigned num_raid_params)
{
	int value, raid10_format = ALGORITHM_RAID10_DEFAULT;
	unsigned raid10_copies = 2;
	unsigned i;
	unsigned region_size = 0;
	sector_t max_io_len;
	const char *arg, *key;
	struct raid_dev *rd;
	struct raid_type *rt = rs->raid_type;

	arg = dm_shift_arg(as);
	num_raid_params--; /* Account for chunk_size argument */

	if (kstrtoint(arg, 10, &value) < 0) {
		rs->ti->error = "Bad numerical argument given for chunk_size";
		return -EINVAL;
	}

	/*
	 * First, parse the in-order required arguments
	 * "chunk_size" is the only argument of this type.
	 */
	if (rt_is_raid1(rt)) {
		if (value)
			DMERR("Ignoring chunk size parameter for RAID 1");
		value = 0;
	} else if (!is_power_of_2(value)) {
		rs->ti->error = "Chunk size must be a power of 2";
		return -EINVAL;
	} else if (value < 8) {
		rs->ti->error = "Chunk size value is too small";
		return -EINVAL;
	}

	rs->md.new_chunk_sectors = rs->md.chunk_sectors = value;

	/*
	 * We set each individual device as In_sync with a completed
	 * 'recovery_offset'.  If there has been a device failure or
	 * replacement then one of the following cases applies:
	 *
	 *   1) User specifies 'rebuild'.
	 *	- Device is reset when param is read.
	 *   2) A new device is supplied.
	 *	- No matching superblock found, resets device.
	 *   3) Device failure was transient and returns on reload.
	 *	- Failure noticed, resets device for bitmap replay.
	 *   4) Device hadn't completed recovery after previous failure.
	 *	- Superblock is read and overrides recovery_offset.
	 *
	 * What is found in the superblocks of the devices is always
	 * authoritative, unless 'rebuild' or '[no]sync' was specified.
	 */
	for (i = 0; i < rs->md.raid_disks; i++) {
		set_bit(In_sync, &rs->dev[i].rdev.flags);
		rs->dev[i].rdev.recovery_offset = MaxSector;
	}

	/*
	 * Second, parse the unordered optional arguments
	 */
	for (i = 0; i < num_raid_params; i++) {
		key = dm_shift_arg(as);
		if (!key) {
			rs->ti->error = "Not enough raid parameters given";
			return -EINVAL;
		}

		if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_NOSYNC))) {
			if (test_and_set_bit(__CTR_FLAG_NOSYNC, &rs->ctr_flags)) {
				rs->ti->error = "Only one 'nosync' argument allowed";
				return -EINVAL;
			}
			rs->md.recovery_cp = MaxSector;
			continue;
		}
		if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_SYNC))) {
			if (test_and_set_bit(__CTR_FLAG_SYNC, &rs->ctr_flags)) {
				rs->ti->error = "Only one 'sync' argument allowed";
				return -EINVAL;
			}
			rs->md.recovery_cp = 0;
			continue;
		}
		if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_RAID10_USE_NEAR_SETS))) {
			if (test_and_set_bit(__CTR_FLAG_RAID10_USE_NEAR_SETS, &rs->ctr_flags)) {
				rs->ti->error = "Only one 'raid10_use_new_sets' argument allowed";
				return -EINVAL;
			}
			continue;
		}

		arg = dm_shift_arg(as);
		i++; /* Account for the argument pairs */
		if (!arg) {
			rs->ti->error = "Wrong number of raid parameters given";
			return -EINVAL;
		}

		/*
		 * Parameters that take a string value are checked here.
		 */

		if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_RAID10_FORMAT))) {
			if (test_and_set_bit(__CTR_FLAG_RAID10_FORMAT, &rs->ctr_flags)) {
				rs->ti->error = "Only one 'raid10_format' argument pair allowed";
				return -EINVAL;
			}
			if (!rt_is_raid10(rt)) {
				rs->ti->error = "'raid10_format' is an invalid parameter for this RAID type";
				return -EINVAL;
			}
			raid10_format = raid10_name_to_format(arg);
			if (raid10_format < 0) {
				rs->ti->error = "Invalid 'raid10_format' value given";
				return raid10_format;
			}
			continue;
		}

		if (kstrtoint(arg, 10, &value) < 0) {
			rs->ti->error = "Bad numerical argument given in raid params";
			return -EINVAL;
		}

		if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_REBUILD))) {
			/*
			 * "rebuild" is being passed in by userspace to provide
			 * indexes of replaced devices and to set up additional
			 * devices on raid level takeover.
			 */
			if (!__within_range(value, 0, rs->raid_disks - 1)) {
				rs->ti->error = "Invalid rebuild index given";
				return -EINVAL;
			}

			if (test_and_set_bit(value, (void *) rs->rebuild_disks)) {
				rs->ti->error = "rebuild for this index already given";
				return -EINVAL;
			}

			rd = rs->dev + value;
			clear_bit(In_sync, &rd->rdev.flags);
			clear_bit(Faulty, &rd->rdev.flags);
			rd->rdev.recovery_offset = 0;
			set_bit(__CTR_FLAG_REBUILD, &rs->ctr_flags);
		} else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_WRITE_MOSTLY))) {
			if (!rt_is_raid1(rt)) {
				rs->ti->error = "write_mostly option is only valid for RAID1";
				return -EINVAL;
			}

			if (!__within_range(value, 0, rs->md.raid_disks - 1)) {
				rs->ti->error = "Invalid write_mostly index given";
				return -EINVAL;
			}

			set_bit(WriteMostly, &rs->dev[value].rdev.flags);
			set_bit(__CTR_FLAG_WRITE_MOSTLY, &rs->ctr_flags);
		} else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_MAX_WRITE_BEHIND))) {
			if (!rt_is_raid1(rt)) {
				rs->ti->error = "max_write_behind option is only valid for RAID1";
				return -EINVAL;
			}

			if (test_and_set_bit(__CTR_FLAG_MAX_WRITE_BEHIND, &rs->ctr_flags)) {
				rs->ti->error = "Only one max_write_behind argument pair allowed";
				return -EINVAL;
			}

			/*
			 * In device-mapper, we specify things in sectors, but
			 * MD records this value in kB
			 */
			value /= 2;
			if (value > COUNTER_MAX) {
				rs->ti->error = "Max write-behind limit out of range";
				return -EINVAL;
			}

			rs->md.bitmap_info.max_write_behind = value;
		} else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_DAEMON_SLEEP))) {
			if (test_and_set_bit(__CTR_FLAG_DAEMON_SLEEP, &rs->ctr_flags)) {
				rs->ti->error = "Only one daemon_sleep argument pair allowed";
				return -EINVAL;
			}
			if (!value || (value > MAX_SCHEDULE_TIMEOUT)) {
				rs->ti->error = "daemon sleep period out of range";
				return -EINVAL;
			}
			rs->md.bitmap_info.daemon_sleep = value;
		} else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_DATA_OFFSET))) {
			/* Userspace passes new data_offset after having extended the the data image LV */
			if (test_and_set_bit(__CTR_FLAG_DATA_OFFSET, &rs->ctr_flags)) {
				rs->ti->error = "Only one data_offset argument pair allowed";
				return -EINVAL;
			}
			/* Ensure sensible data offset */
			if (value < 0) {
				rs->ti->error = "Bogus data_offset value";
				return -EINVAL;
			}
			rs->data_offset = value;
		} else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_DELTA_DISKS))) {
			/* Define the +/-# of disks to add to/remove from the given raid set */
			if (test_and_set_bit(__CTR_FLAG_DELTA_DISKS, &rs->ctr_flags)) {
				rs->ti->error = "Only one delta_disks argument pair allowed";
				return -EINVAL;
			}
			/* Ensure MAX_RAID_DEVICES and raid type minimal_devs! */
			if (!__within_range(abs(value), 1, MAX_RAID_DEVICES - rt->minimal_devs)) {
				rs->ti->error = "Too many delta_disk requested";
				return -EINVAL;
			}

			rs->delta_disks = value;
		} else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_STRIPE_CACHE))) {
			if (test_and_set_bit(__CTR_FLAG_STRIPE_CACHE, &rs->ctr_flags)) {
				rs->ti->error = "Only one stripe_cache argument pair allowed";
				return -EINVAL;
			}

			if (!rt_is_raid456(rt)) {
				rs->ti->error = "Inappropriate argument: stripe_cache";
				return -EINVAL;
			}

			rs->stripe_cache_entries = value;
		} else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_MIN_RECOVERY_RATE))) {
			if (test_and_set_bit(__CTR_FLAG_MIN_RECOVERY_RATE, &rs->ctr_flags)) {
				rs->ti->error = "Only one min_recovery_rate argument pair allowed";
				return -EINVAL;
			}
			if (value > INT_MAX) {
				rs->ti->error = "min_recovery_rate out of range";
				return -EINVAL;
			}
			rs->md.sync_speed_min = (int)value;
		} else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_MAX_RECOVERY_RATE))) {
			if (test_and_set_bit(__CTR_FLAG_MIN_RECOVERY_RATE, &rs->ctr_flags)) {
				rs->ti->error = "Only one max_recovery_rate argument pair allowed";
				return -EINVAL;
			}
			if (value > INT_MAX) {
				rs->ti->error = "max_recovery_rate out of range";
				return -EINVAL;
			}
			rs->md.sync_speed_max = (int)value;
		} else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_REGION_SIZE))) {
			if (test_and_set_bit(__CTR_FLAG_REGION_SIZE, &rs->ctr_flags)) {
				rs->ti->error = "Only one region_size argument pair allowed";
				return -EINVAL;
			}

			region_size = value;
			rs->requested_bitmap_chunk_sectors = value;
		} else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_RAID10_COPIES))) {
			if (test_and_set_bit(__CTR_FLAG_RAID10_COPIES, &rs->ctr_flags)) {
				rs->ti->error = "Only one raid10_copies argument pair allowed";
				return -EINVAL;
			}

			if (!__within_range(value, 2, rs->md.raid_disks)) {
				rs->ti->error = "Bad value for 'raid10_copies'";
				return -EINVAL;
			}

			raid10_copies = value;
		} else {
			DMERR("Unable to parse RAID parameter: %s", key);
			rs->ti->error = "Unable to parse RAID parameter";
			return -EINVAL;
		}
	}

	if (validate_region_size(rs, region_size))
		return -EINVAL;

	if (rs->md.chunk_sectors)
		max_io_len = rs->md.chunk_sectors;
	else
		max_io_len = region_size;

	if (dm_set_target_max_io_len(rs->ti, max_io_len))
		return -EINVAL;

	if (rt_is_raid10(rt)) {
		if (raid10_copies > rs->md.raid_disks) {
			rs->ti->error = "Not enough devices to satisfy specification";
			return -EINVAL;
		}

		rs->md.new_layout = raid10_format_to_md_layout(rs, raid10_format, raid10_copies);
		if (rs->md.new_layout < 0) {
			rs->ti->error = "Error getting raid10 format";
			return rs->md.new_layout;
		}

		rt = get_raid_type_by_ll(10, rs->md.new_layout);
		if (!rt) {
			rs->ti->error = "Failed to recognize new raid10 layout";
			return -EINVAL;
		}

		if ((rt->algorithm == ALGORITHM_RAID10_DEFAULT ||
		     rt->algorithm == ALGORITHM_RAID10_NEAR) &&
		    test_bit(__CTR_FLAG_RAID10_USE_NEAR_SETS, &rs->ctr_flags)) {
			rs->ti->error = "RAID10 format 'near' and 'raid10_use_near_sets' are incompatible";
			return -EINVAL;
		}
	}

	rs->raid10_copies = raid10_copies;

	/* Assume there are no metadata devices until the drives are parsed */
	rs->md.persistent = 0;
	rs->md.external = 1;

	/* Check, if any invalid ctr arguments have been passed in for the raid level */
	return rs_check_for_valid_flags(rs);
}

/* Set raid4/5/6 cache size */
static int rs_set_raid456_stripe_cache(struct raid_set *rs)
{
	int r;
	struct r5conf *conf;
	struct mddev *mddev = &rs->md;
	uint32_t min_stripes = max(mddev->chunk_sectors, mddev->new_chunk_sectors) / 2;
	uint32_t nr_stripes = rs->stripe_cache_entries;

	if (!rt_is_raid456(rs->raid_type)) {
		rs->ti->error = "Inappropriate raid level; cannot change stripe_cache size";
		return -EINVAL;
	}

	if (nr_stripes < min_stripes) {
		DMINFO("Adjusting requested %u stripe cache entries to %u to suit stripe size",
		       nr_stripes, min_stripes);
		nr_stripes = min_stripes;
	}

	conf = mddev->private;
	if (!conf) {
		rs->ti->error = "Cannot change stripe_cache size on inactive RAID set";
		return -EINVAL;
	}

	/* Try setting number of stripes in raid456 stripe cache */
	if (conf->min_nr_stripes != nr_stripes) {
		r = raid5_set_cache_size(mddev, nr_stripes);
		if (r) {
			rs->ti->error = "Failed to set raid4/5/6 stripe cache size";
			return r;
		}

		DMINFO("%u stripe cache entries", nr_stripes);
	}

	return 0;
}

/* Return # of data stripes as kept in mddev as of @rs (i.e. as of superblock) */
static unsigned int mddev_data_stripes(struct raid_set *rs)
{
	return rs->md.raid_disks - rs->raid_type->parity_devs;
}

/* Return # of data stripes of @rs (i.e. as of ctr) */
static unsigned int rs_data_stripes(struct raid_set *rs)
{
	return rs->raid_disks - rs->raid_type->parity_devs;
}

/* Calculate the sectors per device and per array used for @rs */
static int rs_set_dev_and_array_sectors(struct raid_set *rs, bool use_mddev)
{
	int delta_disks;
	unsigned int data_stripes;
	struct mddev *mddev = &rs->md;
	struct md_rdev *rdev;
	sector_t array_sectors = rs->ti->len, dev_sectors = rs->ti->len;
	sector_t cur_dev_sectors = rs->dev[0].rdev.sectors;

	if (use_mddev) {
		delta_disks = mddev->delta_disks;
		data_stripes = mddev_data_stripes(rs);
	} else {
		delta_disks = rs->delta_disks;
		data_stripes = rs_data_stripes(rs);
	}

	/* Special raid1 case w/o delta_disks support (yet) */
	if (rt_is_raid1(rs->raid_type))
		;
	else if (rt_is_raid10(rs->raid_type)) {
		if (rs->raid10_copies < 2 ||
		    delta_disks < 0) {
			rs->ti->error = "Bogus raid10 data copies or delta disks";
			return EINVAL;
		}

		dev_sectors *= rs->raid10_copies;
		if (sector_div(dev_sectors, data_stripes))
			goto bad;

		array_sectors = (data_stripes + delta_disks) * dev_sectors;
		if (sector_div(array_sectors, rs->raid10_copies))
			goto bad;

	} else if (sector_div(dev_sectors, data_stripes))
		goto bad;

	else
		/* Striped layouts */
		array_sectors = (data_stripes + delta_disks) * dev_sectors;

	rdev_for_each(rdev, mddev)
		rdev->sectors = dev_sectors;

	mddev->array_sectors = array_sectors;
	mddev->dev_sectors = dev_sectors;

	if (!rs_is_raid0(rs) && dev_sectors > cur_dev_sectors)
		mddev->recovery_cp = dev_sectors;

	return 0;
bad:
	rs->ti->error = "Target length not divisible by number of data devices";
	return EINVAL;
}

static void do_table_event(struct work_struct *ws)
{
	struct raid_set *rs = container_of(ws, struct raid_set, md.event_work);

	rs_set_capacity(rs);
	dm_table_event(rs->ti->table);
}

static int raid_is_congested(struct dm_target_callbacks *cb, int bits)
{
	struct raid_set *rs = container_of(cb, struct raid_set, callbacks);

	return mddev_congested(&rs->md, bits);
}

/*
 * Make sure a valid takover (level switch) is being requested on @rs
 *
 * Conversions of raid sets from one MD personality to another
 * have to conform to restrictions which are enforced here.
 *
 * Degration is already checked for in rs_check_conversion() below.
 */
static int rs_check_takeover(struct raid_set *rs)
{
	struct mddev *mddev = &rs->md;
	unsigned int near_copies;

	smp_rmb();
	if (rs->md.degraded) {
		rs->ti->error = "Can't takeover degraded raid set";
		return -EPERM;
	}

	if (rs_is_reshaping(rs)) {
		rs->ti->error = "Can't takeover reshaping raid set";
		return -EPERM;
	}

	switch (mddev->level) {
	case 0:
		/* raid0 -> raid1/5 with one disk */
		if ((mddev->new_level == 1 || mddev->new_level == 5) &&
		    mddev->raid_disks == 1)
			return 0;

		/* raid0 -> raid10 */
		if (mddev->new_level == 10 &&
		    !(rs->raid_disks % mddev->raid_disks))
			return 0;

		/* raid0 with multiple disks -> raid4/5/6 */
		if (__within_range(mddev->new_level, 4, 6) &&
		    mddev->new_layout == ALGORITHM_PARITY_N &&
		    mddev->raid_disks > 1)
			return 0;

		break;

	case 10:
		/* Can't takeover raid10_offset! */
		if (__is_raid10_offset(mddev->layout))
			break;

		near_copies = __raid10_near_copies(mddev->layout);

		/* raid10* -> raid0 */
		if (mddev->new_level == 0) {
			/* Can takeover raid10_near with raid disks divisable by data copies! */
			if (near_copies > 1 &&
			    !(mddev->raid_disks % near_copies)) {
				mddev->raid_disks /= near_copies;
				mddev->delta_disks = mddev->raid_disks;
				return 0;
			}

			/* Can takeover raid10_far */
			if (near_copies == 1 &&
			    __raid10_far_copies(mddev->layout) > 1)
				return 0;

			break;
		}

		/* raid10_{near,far} -> raid1 */
		if (mddev->new_level == 1 &&
		    max(near_copies, __raid10_far_copies(mddev->layout)) == mddev->raid_disks)
			return 0;

		/* raid10_{near,far} with 2 disks -> raid4/5 */
		if (__within_range(mddev->new_level, 4, 5) &&
		    mddev->raid_disks == 2)
			return 0;
		break;

	case 1:
		/* raid1 with 2 disks -> raid4/5 */
		if (__within_range(mddev->new_level, 4, 5) &&
		    mddev->raid_disks == 2) {
			mddev->degraded = 1;
			return 0;
		}

		/* raid1 -> raid0 */
		if (mddev->new_level == 0 &&
		    mddev->raid_disks == 1)
			return 0;

		/* raid1 -> raid10 */
		if (mddev->new_level == 10)
			return 0;

		break;

	case 4:
		/* raid4 -> raid0 */
		if (mddev->new_level == 0)
			return 0;

		/* raid4 -> raid1/5 with 2 disks */
		if ((mddev->new_level == 1 || mddev->new_level == 5) &&
		    mddev->raid_disks == 2)
			return 0;

		/* raid4 -> raid5/6 with parity N */
		if (__within_range(mddev->new_level, 5, 6) &&
		    mddev->layout == ALGORITHM_PARITY_N)
			return 0;
		break;

	case 5:
		/* raid5 with parity N -> raid0 */
		if (mddev->new_level == 0 &&
		    mddev->layout == ALGORITHM_PARITY_N)
			return 0;

		/* raid5 with parity N -> raid4 */
		if (mddev->new_level == 4 &&
		    mddev->layout == ALGORITHM_PARITY_N)
			return 0;

		/* raid5 with 2 disks -> raid1/4/10 */
		if ((mddev->new_level == 1 || mddev->new_level == 4 || mddev->new_level == 10) &&
		    mddev->raid_disks == 2)
			return 0;

		/* raid5 with parity N -> raid6 with parity N */
		if (mddev->new_level == 6 &&
		    ((mddev->layout == ALGORITHM_PARITY_N && mddev->new_layout == ALGORITHM_PARITY_N) ||
		      __within_range(mddev->new_layout, ALGORITHM_LEFT_ASYMMETRIC_6, ALGORITHM_RIGHT_SYMMETRIC_6)))
			return 0;
		break;

	case 6:
		/* raid6 with parity N -> raid0 */
		if (mddev->new_level == 0 &&
		    mddev->layout == ALGORITHM_PARITY_N)
			return 0;

		/* raid6 with parity N -> raid4 */
		if (mddev->new_level == 4 &&
		    mddev->layout == ALGORITHM_PARITY_N)
			return 0;

		/* raid6_*_n with parity N -> raid5_* */
		if (mddev->new_level == 5 &&
		    ((mddev->layout == ALGORITHM_PARITY_N && mddev->new_layout == ALGORITHM_PARITY_N) ||
		     __within_range(mddev->new_layout, ALGORITHM_LEFT_ASYMMETRIC, ALGORITHM_RIGHT_SYMMETRIC)))
			return 0;

	default:
		break;
	}

	rs->ti->error = "takeover not possible";
	return -EINVAL;
}

/* True if @rs requested to be taken over */
static bool rs_takeover_requested(struct raid_set *rs)
{
	return rs->md.new_level != rs->md.level;
}

/* True if @rs is requested to reshape by ctr */
static bool rs_reshape_requested(struct raid_set *rs)
{
	struct mddev *mddev = &rs->md;

	if (!mddev->level)
		return false;

	return !__is_raid10_far(mddev->new_layout) &&
	       mddev->new_level == mddev->level &&
	       (mddev->new_layout != mddev->layout ||
		mddev->new_chunk_sectors != mddev->chunk_sectors ||
		rs->raid_disks + rs->delta_disks != mddev->raid_disks);
}

/*  Features */
#define	FEATURE_FLAG_SUPPORTS_V190	0x1 /* Supports extended superblock */

/* State flags for sb->flags */
#define	SB_FLAG_RESHAPE_ACTIVE		0x1
#define	SB_FLAG_RESHAPE_BACKWARDS	0x2

/*
 * This structure is never routinely used by userspace, unlike md superblocks.
 * Devices with this superblock should only ever be accessed via device-mapper.
 */
#define DM_RAID_MAGIC 0x64526D44
struct dm_raid_superblock {
	__le32 magic;		/* "DmRd" */
	__le32 compat_features;	/* Used to indicate compatible features (like 1.9.0 ondisk metadata extension) */

	__le32 num_devices;	/* Number of devices in this raid set. (Max 64) */
	__le32 array_position;	/* The position of this drive in the raid set */

	__le64 events;		/* Incremented by md when superblock updated */
	__le64 failed_devices;	/* Pre 1.9.0 part of bit field of devices to */
				/* indicate failures (see extension below) */

	/*
	 * This offset tracks the progress of the repair or replacement of
	 * an individual drive.
	 */
	__le64 disk_recovery_offset;

	/*
	 * This offset tracks the progress of the initial raid set
	 * synchronisation/parity calculation.
	 */
	__le64 array_resync_offset;

	/*
	 * raid characteristics
	 */
	__le32 level;
	__le32 layout;
	__le32 stripe_sectors;

	/********************************************************************
	 * BELOW FOLLOW V1.9.0 EXTENSIONS TO THE PRISTINE SUPERBLOCK FORMAT!!!
	 *
	 * FEATURE_FLAG_SUPPORTS_V190 in the features member indicates that those exist
	 */

	__le32 flags; /* Flags defining array states for reshaping */

	/*
	 * This offset tracks the progress of a raid
	 * set reshape in order to be able to restart it
	 */
	__le64 reshape_position;

	/*
	 * These define the properties of the array in case of an interrupted reshape
	 */
	__le32 new_level;
	__le32 new_layout;
	__le32 new_stripe_sectors;
	__le32 delta_disks;

	__le64 array_sectors; /* Array size in sectors */

	/*
	 * Sector offsets to data on devices (reshaping).
	 * Needed to support out of place reshaping, thus
	 * not writing over any stripes whilst converting
	 * them from old to new layout
	 */
	__le64 data_offset;
	__le64 new_data_offset;

	__le64 sectors; /* Used device size in sectors */

	/*
	 * Additonal Bit field of devices indicating failures to support
	 * up to 256 devices with the 1.9.0 on-disk metadata format
	 */
	__le64 extended_failed_devices[DISKS_ARRAY_ELEMS - 1];

	__le32 incompat_features;	/* Used to indicate any incompatible features */

	/* Always set rest up to logical block size to 0 when writing (see get_metadata_device() below). */
} __packed;

/*
 * Check for reshape constraints on raid set @rs:
 *
 * - reshape function non-existent
 * - degraded set
 * - ongoing recovery
 * - ongoing reshape
 *
 * Returns 0 if none or -EPERM if given constraint
 * and error message reference in @errmsg
 */
static int rs_check_reshape(struct raid_set *rs)
{
	struct mddev *mddev = &rs->md;

	smp_rmb(); /* Make sure we access recent reshape position */

	if (!mddev->pers || !mddev->pers->check_reshape)
		rs->ti->error = "Reshape not supported";
	else if (mddev->degraded)
		rs->ti->error = "Can't reshape degraded raid set";
	else if (rs_is_recovering(rs))
		rs->ti->error = "Convert request on recovering raid set prohibited";
	else if (mddev->reshape_position && rs_is_reshaping(rs))
		rs->ti->error = "raid set already reshaping!";
	else if (!(rs_is_raid10(rs) || rs_is_raid456(rs)))
		rs->ti->error = "Reshaping only supported for raid4/5/6/10";
	else
		return 0;

	return -EPERM;
}

static int read_disk_sb(struct md_rdev *rdev, int size)
{
	BUG_ON(!rdev->sb_page);

	if (rdev->sb_loaded)
		return 0;

	if (!sync_page_io(rdev, 0, size, rdev->sb_page, REQ_OP_READ, 0, 1)) {
		DMERR("Failed to read superblock of device at position %d",
		      rdev->raid_disk);
		md_error(rdev->mddev, rdev);
		return -EINVAL;
	}

	rdev->sb_loaded = 1;

	return 0;
}

static void sb_retrieve_failed_devices(struct dm_raid_superblock *sb, uint64_t *failed_devices)
{
	failed_devices[0] = le64_to_cpu(sb->failed_devices);
	memset(failed_devices + 1, 0, sizeof(sb->extended_failed_devices));

	if (le32_to_cpu(sb->compat_features) & FEATURE_FLAG_SUPPORTS_V190) {
		int i = ARRAY_SIZE(sb->extended_failed_devices);

		while (i--)
			failed_devices[i+1] = le64_to_cpu(sb->extended_failed_devices[i]);
	}
}

static void sb_update_failed_devices(struct dm_raid_superblock *sb, uint64_t *failed_devices)
{
	int i = ARRAY_SIZE(sb->extended_failed_devices);

	sb->failed_devices = cpu_to_le64(failed_devices[0]);
	while (i--)
		sb->extended_failed_devices[i] = cpu_to_le64(failed_devices[i+1]);
}

/*
 * Synchronize the superblock members with the raid set properties
 *
 * All superblock data is little endian.
 */
static void super_sync(struct mddev *mddev, struct md_rdev *rdev)
{
	bool update_failed_devices = false;
	unsigned int i;
	uint64_t failed_devices[DISKS_ARRAY_ELEMS];
	struct dm_raid_superblock *sb;
	struct raid_set *rs = container_of(mddev, struct raid_set, md);

	/* No metadata device, no superblock */
	if (!rdev->meta_bdev)
		return;

	BUG_ON(!rdev->sb_page);

	sb = page_address(rdev->sb_page);

	sb_retrieve_failed_devices(sb, failed_devices);

	for (i = 0; i < rs->raid_disks; i++)
		if (!rs->dev[i].data_dev || test_bit(Faulty, &rs->dev[i].rdev.flags)) {
			update_failed_devices = true;
			set_bit(i, (void *) failed_devices);
		}

	if (update_failed_devices)
		sb_update_failed_devices(sb, failed_devices);

	sb->magic = cpu_to_le32(DM_RAID_MAGIC);
	sb->compat_features = cpu_to_le32(FEATURE_FLAG_SUPPORTS_V190);

	sb->num_devices = cpu_to_le32(mddev->raid_disks);
	sb->array_position = cpu_to_le32(rdev->raid_disk);

	sb->events = cpu_to_le64(mddev->events);

	sb->disk_recovery_offset = cpu_to_le64(rdev->recovery_offset);
	sb->array_resync_offset = cpu_to_le64(mddev->recovery_cp);

	sb->level = cpu_to_le32(mddev->level);
	sb->layout = cpu_to_le32(mddev->layout);
	sb->stripe_sectors = cpu_to_le32(mddev->chunk_sectors);

	sb->new_level = cpu_to_le32(mddev->new_level);
	sb->new_layout = cpu_to_le32(mddev->new_layout);
	sb->new_stripe_sectors = cpu_to_le32(mddev->new_chunk_sectors);

	sb->delta_disks = cpu_to_le32(mddev->delta_disks);

	smp_rmb(); /* Make sure we access most recent reshape position */
	sb->reshape_position = cpu_to_le64(mddev->reshape_position);
	if (le64_to_cpu(sb->reshape_position) != MaxSector) {
		/* Flag ongoing reshape */
		sb->flags |= cpu_to_le32(SB_FLAG_RESHAPE_ACTIVE);

		if (mddev->delta_disks < 0 || mddev->reshape_backwards)
			sb->flags |= cpu_to_le32(SB_FLAG_RESHAPE_BACKWARDS);
	} else {
		/* Clear reshape flags */
		sb->flags &= ~(cpu_to_le32(SB_FLAG_RESHAPE_ACTIVE|SB_FLAG_RESHAPE_BACKWARDS));
	}

	sb->array_sectors = cpu_to_le64(mddev->array_sectors);
	sb->data_offset = cpu_to_le64(rdev->data_offset);
	sb->new_data_offset = cpu_to_le64(rdev->new_data_offset);
	sb->sectors = cpu_to_le64(rdev->sectors);

	/* Zero out the rest of the payload after the size of the superblock */
	memset(sb + 1, 0, rdev->sb_size - sizeof(*sb));
}

/*
 * super_load
 *
 * This function creates a superblock if one is not found on the device
 * and will decide which superblock to use if there's a choice.
 *
 * Return: 1 if use rdev, 0 if use refdev, -Exxx otherwise
 */
static int super_load(struct md_rdev *rdev, struct md_rdev *refdev)
{
	int r;
	struct dm_raid_superblock *sb;
	struct dm_raid_superblock *refsb;
	uint64_t events_sb, events_refsb;

	rdev->sb_start = 0;
	rdev->sb_size = bdev_logical_block_size(rdev->meta_bdev);
	if (rdev->sb_size < sizeof(*sb) || rdev->sb_size > PAGE_SIZE) {
		DMERR("superblock size of a logical block is no longer valid");
		return -EINVAL;
	}

	r = read_disk_sb(rdev, rdev->sb_size);
	if (r)
		return r;

	sb = page_address(rdev->sb_page);

	/*
	 * Two cases that we want to write new superblocks and rebuild:
	 * 1) New device (no matching magic number)
	 * 2) Device specified for rebuild (!In_sync w/ offset == 0)
	 */
	if ((sb->magic != cpu_to_le32(DM_RAID_MAGIC)) ||
	    (!test_bit(In_sync, &rdev->flags) && !rdev->recovery_offset)) {
		super_sync(rdev->mddev, rdev);

		set_bit(FirstUse, &rdev->flags);
		sb->compat_features = cpu_to_le32(FEATURE_FLAG_SUPPORTS_V190);

		/* Force writing of superblocks to disk */
		set_bit(MD_CHANGE_DEVS, &rdev->mddev->flags);

		/* Any superblock is better than none, choose that if given */
		return refdev ? 0 : 1;
	}

	if (!refdev)
		return 1;

	events_sb = le64_to_cpu(sb->events);

	refsb = page_address(refdev->sb_page);
	events_refsb = le64_to_cpu(refsb->events);

	return (events_sb > events_refsb) ? 1 : 0;
}

static int super_init_validation(struct raid_set *rs, struct md_rdev *rdev)
{
	int role;
	unsigned int d;
	struct mddev *mddev = &rs->md;
	uint64_t events_sb;
	uint64_t failed_devices[DISKS_ARRAY_ELEMS];
	struct dm_raid_superblock *sb;
	uint32_t new_devs = 0, rebuild_and_new = 0, rebuilds = 0;
	struct md_rdev *r;
	struct dm_raid_superblock *sb2;

	sb = page_address(rdev->sb_page);
	events_sb = le64_to_cpu(sb->events);

	/*
	 * Initialise to 1 if this is a new superblock.
	 */
	mddev->events = events_sb ? : 1;

	mddev->reshape_position = MaxSector;

	/*
	 * Reshaping is supported, e.g. reshape_position is valid
	 * in superblock and superblock content is authoritative.
	 */
	if (le32_to_cpu(sb->compat_features) & FEATURE_FLAG_SUPPORTS_V190) {
		/* Superblock is authoritative wrt given raid set layout! */
		mddev->raid_disks = le32_to_cpu(sb->num_devices);
		mddev->level = le32_to_cpu(sb->level);
		mddev->layout = le32_to_cpu(sb->layout);
		mddev->chunk_sectors = le32_to_cpu(sb->stripe_sectors);
		mddev->new_level = le32_to_cpu(sb->new_level);
		mddev->new_layout = le32_to_cpu(sb->new_layout);
		mddev->new_chunk_sectors = le32_to_cpu(sb->new_stripe_sectors);
		mddev->delta_disks = le32_to_cpu(sb->delta_disks);
		mddev->array_sectors = le64_to_cpu(sb->array_sectors);

		/* raid was reshaping and got interrupted */
		if (le32_to_cpu(sb->flags) & SB_FLAG_RESHAPE_ACTIVE) {
			if (test_bit(__CTR_FLAG_DELTA_DISKS, &rs->ctr_flags)) {
				DMERR("Reshape requested but raid set is still reshaping");
				return -EINVAL;
			}

			if (mddev->delta_disks < 0 ||
			    (!mddev->delta_disks && (le32_to_cpu(sb->flags) & SB_FLAG_RESHAPE_BACKWARDS)))
				mddev->reshape_backwards = 1;
			else
				mddev->reshape_backwards = 0;

			mddev->reshape_position = le64_to_cpu(sb->reshape_position);
			rs->raid_type = get_raid_type_by_ll(mddev->level, mddev->layout);
		}

	} else {
		/*
		 * No takeover/reshaping, because we don't have the extended v1.9.0 metadata
		 */
		if (le32_to_cpu(sb->level) != mddev->level) {
			DMERR("Reshaping/takeover raid sets not yet supported. (raid level/stripes/size change)");
			return -EINVAL;
		}
		if (le32_to_cpu(sb->layout) != mddev->layout) {
			DMERR("Reshaping raid sets not yet supported. (raid layout change)");
			DMERR("	 0x%X vs 0x%X", le32_to_cpu(sb->layout), mddev->layout);
			DMERR("	 Old layout: %s w/ %d copies",
			      raid10_md_layout_to_format(le32_to_cpu(sb->layout)),
			      raid10_md_layout_to_copies(le32_to_cpu(sb->layout)));
			DMERR("	 New layout: %s w/ %d copies",
			      raid10_md_layout_to_format(mddev->layout),
			      raid10_md_layout_to_copies(mddev->layout));
			return -EINVAL;
		}
		if (le32_to_cpu(sb->stripe_sectors) != mddev->chunk_sectors) {
			DMERR("Reshaping raid sets not yet supported. (stripe sectors change)");
			return -EINVAL;
		}

		/* We can only change the number of devices in raid1 with old (i.e. pre 1.0.7) metadata */
		if (!rt_is_raid1(rs->raid_type) &&
		    (le32_to_cpu(sb->num_devices) != mddev->raid_disks)) {
			DMERR("Reshaping raid sets not yet supported. (device count change from %u to %u)",
			      sb->num_devices, mddev->raid_disks);
			return -EINVAL;
		}

		/* Table line is checked vs. authoritative superblock */
		rs_set_new(rs);
	}

	if (!test_bit(__CTR_FLAG_NOSYNC, &rs->ctr_flags))
		mddev->recovery_cp = le64_to_cpu(sb->array_resync_offset);

	/*
	 * During load, we set FirstUse if a new superblock was written.
	 * There are two reasons we might not have a superblock:
	 * 1) The raid set is brand new - in which case, all of the
	 *    devices must have their In_sync bit set.	Also,
	 *    recovery_cp must be 0, unless forced.
	 * 2) This is a new device being added to an old raid set
	 *    and the new device needs to be rebuilt - in which
	 *    case the In_sync bit will /not/ be set and
	 *    recovery_cp must be MaxSector.
	 * 3) This is/are a new device(s) being added to an old
	 *    raid set during takeover to a higher raid level
	 *    to provide capacity for redundancy or during reshape
	 *    to add capacity to grow the raid set.
	 */
	d = 0;
	rdev_for_each(r, mddev) {
		if (test_bit(FirstUse, &r->flags))
			new_devs++;

		if (!test_bit(In_sync, &r->flags)) {
			DMINFO("Device %d specified for rebuild; clearing superblock",
				r->raid_disk);
			rebuilds++;

			if (test_bit(FirstUse, &r->flags))
				rebuild_and_new++;
		}

		d++;
	}

	if (new_devs == rs->raid_disks || !rebuilds) {
		/* Replace a broken device */
		if (new_devs == 1 && !rs->delta_disks)
			;
		if (new_devs == rs->raid_disks) {
			DMINFO("Superblocks created for new raid set");
			set_bit(MD_ARRAY_FIRST_USE, &mddev->flags);
			mddev->recovery_cp = 0;
		} else if (new_devs != rebuilds &&
			   new_devs != rs->delta_disks) {
			DMERR("New device injected into existing raid set without "
			      "'delta_disks' or 'rebuild' parameter specified");
			return -EINVAL;
		}
	} else if (new_devs && new_devs != rebuilds) {
		DMERR("%u 'rebuild' devices cannot be injected into"
		      " a raid set with %u other first-time devices",
		      rebuilds, new_devs);
		return -EINVAL;
	} else if (rebuilds) {
		if (rebuild_and_new && rebuilds != rebuild_and_new) {
			DMERR("new device%s provided without 'rebuild'",
			      new_devs > 1 ? "s" : "");
			return -EINVAL;
		} else if (rs_is_recovering(rs)) {
			DMERR("'rebuild' specified while raid set is not in-sync (recovery_cp=%llu)",
			      (unsigned long long) mddev->recovery_cp);
			return -EINVAL;
		} else if (rs_is_reshaping(rs)) {
			DMERR("'rebuild' specified while raid set is being reshaped (reshape_position=%llu)",
			      (unsigned long long) mddev->reshape_position);
			return -EINVAL;
		}
	}

	/*
	 * Now we set the Faulty bit for those devices that are
	 * recorded in the superblock as failed.
	 */
	sb_retrieve_failed_devices(sb, failed_devices);
	rdev_for_each(r, mddev) {
		if (!r->sb_page)
			continue;
		sb2 = page_address(r->sb_page);
		sb2->failed_devices = 0;
		memset(sb2->extended_failed_devices, 0, sizeof(sb2->extended_failed_devices));

		/*
		 * Check for any device re-ordering.
		 */
		if (!test_bit(FirstUse, &r->flags) && (r->raid_disk >= 0)) {
			role = le32_to_cpu(sb2->array_position);
			if (role < 0)
				continue;

			if (role != r->raid_disk) {
				if (__is_raid10_near(mddev->layout)) {
					if (mddev->raid_disks % __raid10_near_copies(mddev->layout) ||
					    rs->raid_disks % rs->raid10_copies) {
						rs->ti->error =
							"Cannot change raid10 near set to odd # of devices!";
						return -EINVAL;
					}

					sb2->array_position = cpu_to_le32(r->raid_disk);

				} else if (!(rs_is_raid10(rs) && rt_is_raid0(rs->raid_type)) &&
					   !(rs_is_raid0(rs) && rt_is_raid10(rs->raid_type)) &&
					   !rt_is_raid1(rs->raid_type)) {
					rs->ti->error = "Cannot change device positions in raid set";
					return -EINVAL;
				}

				DMINFO("raid device #%d now at position #%d", role, r->raid_disk);
			}

			/*
			 * Partial recovery is performed on
			 * returning failed devices.
			 */
			if (test_bit(role, (void *) failed_devices))
				set_bit(Faulty, &r->flags);
		}
	}

	return 0;
}

static int super_validate(struct raid_set *rs, struct md_rdev *rdev)
{
	struct mddev *mddev = &rs->md;
	struct dm_raid_superblock *sb;

	if (rs_is_raid0(rs) || !rdev->sb_page)
		return 0;

	sb = page_address(rdev->sb_page);

	/*
	 * If mddev->events is not set, we know we have not yet initialized
	 * the array.
	 */
	if (!mddev->events && super_init_validation(rs, rdev))
		return -EINVAL;

	if (le32_to_cpu(sb->compat_features) != FEATURE_FLAG_SUPPORTS_V190) {
		rs->ti->error = "Unable to assemble array: Unknown flag(s) in compatible feature flags";
		return -EINVAL;
	}

	if (sb->incompat_features) {
		rs->ti->error = "Unable to assemble array: No incompatible feature flags supported yet";
		return -EINVAL;
	}

	/* Enable bitmap creation for RAID levels != 0 */
	mddev->bitmap_info.offset = rt_is_raid0(rs->raid_type) ? 0 : to_sector(4096);
	rdev->mddev->bitmap_info.default_offset = mddev->bitmap_info.offset;

	if (!test_and_clear_bit(FirstUse, &rdev->flags)) {
		/* Retrieve device size stored in superblock to be prepared for shrink */
		rdev->sectors = le64_to_cpu(sb->sectors);
		rdev->recovery_offset = le64_to_cpu(sb->disk_recovery_offset);
		if (rdev->recovery_offset == MaxSector)
			set_bit(In_sync, &rdev->flags);
		/*
		 * If no reshape in progress -> we're recovering single
		 * disk(s) and have to set the device(s) to out-of-sync
		 */
		else if (!rs_is_reshaping(rs))
			clear_bit(In_sync, &rdev->flags); /* Mandatory for recovery */
	}

	/*
	 * If a device comes back, set it as not In_sync and no longer faulty.
	 */
	if (test_and_clear_bit(Faulty, &rdev->flags)) {
		rdev->recovery_offset = 0;
		clear_bit(In_sync, &rdev->flags);
		rdev->saved_raid_disk = rdev->raid_disk;
	}

	/* Reshape support -> restore repective data offsets */
	rdev->data_offset = le64_to_cpu(sb->data_offset);
	rdev->new_data_offset = le64_to_cpu(sb->new_data_offset);

	return 0;
}

/*
 * Analyse superblocks and select the freshest.
 */
static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
{
	int r;
	struct raid_dev *dev;
	struct md_rdev *rdev, *tmp, *freshest;
	struct mddev *mddev = &rs->md;

	freshest = NULL;
	rdev_for_each_safe(rdev, tmp, mddev) {
		/*
		 * Skipping super_load due to CTR_FLAG_SYNC will cause
		 * the array to undergo initialization again as
		 * though it were new.	This is the intended effect
		 * of the "sync" directive.
		 *
		 * When reshaping capability is added, we must ensure
		 * that the "sync" directive is disallowed during the
		 * reshape.
		 */
		if (test_bit(__CTR_FLAG_SYNC, &rs->ctr_flags))
			continue;

		if (!rdev->meta_bdev)
			continue;

		r = super_load(rdev, freshest);

		switch (r) {
		case 1:
			freshest = rdev;
			break;
		case 0:
			break;
		default:
			dev = container_of(rdev, struct raid_dev, rdev);
			if (dev->meta_dev)
				dm_put_device(ti, dev->meta_dev);

			dev->meta_dev = NULL;
			rdev->meta_bdev = NULL;

			if (rdev->sb_page)
				put_page(rdev->sb_page);

			rdev->sb_page = NULL;

			rdev->sb_loaded = 0;

			/*
			 * We might be able to salvage the data device
			 * even though the meta device has failed.  For
			 * now, we behave as though '- -' had been
			 * set for this device in the table.
			 */
			if (dev->data_dev)
				dm_put_device(ti, dev->data_dev);

			dev->data_dev = NULL;
			rdev->bdev = NULL;

			list_del(&rdev->same_set);
		}
	}

	if (!freshest)
		return 0;

	if (validate_raid_redundancy(rs)) {
		rs->ti->error = "Insufficient redundancy to activate array";
		return -EINVAL;
	}

	/*
	 * Validation of the freshest device provides the source of
	 * validation for the remaining devices.
	 */
	rs->ti->error = "Unable to assemble array: Invalid superblocks";
	if (super_validate(rs, freshest))
		return -EINVAL;

	rdev_for_each(rdev, mddev)
		if ((rdev != freshest) && super_validate(rs, rdev))
			return -EINVAL;
	return 0;
}

/*
 * Adjust data_offset and new_data_offset on all disk members of @rs
 * for out of place reshaping if requested by contructor
 *
 * We need free space at the beginning of each raid disk for forward
 * and at the end for backward reshapes which userspace has to provide
 * via remapping/reordering of space.
 */
static int rs_adjust_data_offsets(struct raid_set *rs)
{
	sector_t data_offset = 0, new_data_offset = 0;
	struct md_rdev *rdev;

	/* Constructor did not request data offset change */
	if (!test_bit(__CTR_FLAG_DATA_OFFSET, &rs->ctr_flags)) {
		if (!rs_is_reshapable(rs))
			goto out;

		return 0;
	}

	/* HM FIXME: get InSync raid_dev? */
	rdev = &rs->dev[0].rdev;

	if (rs->delta_disks < 0) {
		/*
		 * Removing disks (reshaping backwards):
		 *
		 * - before reshape: data is at offset 0 and free space
		 *		     is at end of each component LV
		 *
		 * - after reshape: data is at offset rs->data_offset != 0 on each component LV
		 */
		data_offset = 0;
		new_data_offset = rs->data_offset;

	} else if (rs->delta_disks > 0) {
		/*
		 * Adding disks (reshaping forwards):
		 *
		 * - before reshape: data is at offset rs->data_offset != 0 and
		 *		     free space is at begin of each component LV
		 *
		 * - after reshape: data is at offset 0 on each component LV
		 */
		data_offset = rs->data_offset;
		new_data_offset = 0;

	} else {
		/*
		 * User space passes in 0 for data offset after having removed reshape space
		 *
		 * - or - (data offset != 0)
		 *
		 * Changing RAID layout or chunk size -> toggle offsets
		 *
		 * - before reshape: data is at offset rs->data_offset 0 and
		 *		     free space is at end of each component LV
		 *		     -or-
		 *                   data is at offset rs->data_offset != 0 and
		 *		     free space is at begin of each component LV
		 *
		 * - after reshape: data is at offset 0 if i was at offset != 0
		 *                  of at offset != 0 if it was at offset 0
		 *                  on each component LV
		 *
		 */
		data_offset = rs->data_offset ? rdev->data_offset : 0;
		new_data_offset = data_offset ? 0 : rs->data_offset;
		set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags);
	}

	/*
	 * Make sure we got a minimum amount of free sectors per device
	 */
	if (rs->data_offset &&
	    to_sector(i_size_read(rdev->bdev->bd_inode)) - rdev->sectors < MIN_FREE_RESHAPE_SPACE) {
		rs->ti->error = data_offset ? "No space for forward reshape" :
					      "No space for backward reshape";
		return -ENOSPC;
	}
out:
	/* Adjust data offsets on all rdevs */
	rdev_for_each(rdev, &rs->md) {
		rdev->data_offset = data_offset;
		rdev->new_data_offset = new_data_offset;
	}

	return 0;
}

/* Userpace reordered disks -> adjust raid_disk indexes in @rs */
static void __reorder_raid_disk_indexes(struct raid_set *rs)
{
	int i = 0;
	struct md_rdev *rdev;

	rdev_for_each(rdev, &rs->md) {
		rdev->raid_disk = i++;
		rdev->saved_raid_disk = rdev->new_raid_disk = -1;
	}
}

/*
 * Setup @rs for takeover by a different raid level
 */
static int rs_setup_takeover(struct raid_set *rs)
{
	struct mddev *mddev = &rs->md;
	struct md_rdev *rdev;
	unsigned int d = mddev->raid_disks = rs->raid_disks;
	sector_t new_data_offset = rs->dev[0].rdev.data_offset ? 0 : rs->data_offset;

	if (rt_is_raid10(rs->raid_type)) {
		if (mddev->level == 0) {
			/* Userpace reordered disks -> adjust raid_disk indexes */
			__reorder_raid_disk_indexes(rs);

			/* raid0 -> raid10_far layout */
			mddev->layout = raid10_format_to_md_layout(rs, ALGORITHM_RAID10_FAR,
								   rs->raid10_copies);
		} else if (mddev->level == 1)
			/* raid1 -> raid10_near layout */
			mddev->layout = raid10_format_to_md_layout(rs, ALGORITHM_RAID10_NEAR,
								   rs->raid_disks);
		 else
			return -EINVAL;

	}

	clear_bit(MD_ARRAY_FIRST_USE, &mddev->flags);
	mddev->recovery_cp = MaxSector;

	while (d--) {
		rdev = &rs->dev[d].rdev;

		if (test_bit(d, (void *) rs->rebuild_disks)) {
			clear_bit(In_sync, &rdev->flags);
			clear_bit(Faulty, &rdev->flags);
			mddev->recovery_cp = rdev->recovery_offset = 0;
			/* Bitmap has to be created when we do an "up" takeover */
			set_bit(MD_ARRAY_FIRST_USE, &mddev->flags);
		}

		rdev->new_data_offset = new_data_offset;
	}

	return 0;
}

/*
 *
 * - change raid layout
 * - change chunk size
 * - add disks
 * - remove disks
 */
static int rs_setup_reshape(struct raid_set *rs)
{
	int r = 0;
	unsigned int cur_raid_devs, d;
	struct mddev *mddev = &rs->md;
	struct md_rdev *rdev;

	mddev->delta_disks = rs->delta_disks;
	cur_raid_devs = mddev->raid_disks;

	/* Ignore impossible layout change whilst adding/removing disks */
	if (mddev->delta_disks &&
	    mddev->layout != mddev->new_layout) {
		DMINFO("Ignoring invalid layout change with delta_disks=%d", rs->delta_disks);
		mddev->new_layout = mddev->layout;
	}

	/*
	 * Adjust array size:
	 *
	 * - in case of adding disks, array size has
	 *   to grow after the disk adding reshape,
	 *   which'll hapen in the event handler;
	 *   reshape will happen forward, so space has to
	 *   be available at the beginning of each disk
	 *
	 * - in case of removing disks, array size
	 *   has to shrink before starting the reshape,
	 *   which'll happen here;
	 *   reshape will happen backward, so space has to
	 *   be available at the end of each disk
	 *
	 * - data_offset and new_data_offset are
	 *   adjusted for afreentioned out of place
	 *   reshaping based on userspace passing in
	 *   the "data_offset <sectors>" key/value
	 *   pair via te constructor
	 */

	/* Add disk(s) */
	if (rs->delta_disks > 0) {
		/* Prepare disks for check in raid4/5/6/10 {check|start}_reshape */
		for (d = cur_raid_devs; d < rs->raid_disks; d++) {
			rdev = &rs->dev[d].rdev;
			clear_bit(In_sync, &rdev->flags);

			/*
			 * save_raid_disk needs to be -1, or recovery_offset will be set to 0
			 * by md, which'll store that erroneously in the superblock on reshape
			 */
			rdev->saved_raid_disk = -1;
			rdev->raid_disk = d;

			rdev->sectors = mddev->dev_sectors;
			rdev->recovery_offset = MaxSector;
		}

		mddev->reshape_backwards = 0; /* adding disks -> forward reshape */

	/* Remove disk(s) */
	} else if (rs->delta_disks < 0) {
		r = rs_set_dev_and_array_sectors(rs, true);
		mddev->reshape_backwards = 1; /* removing disk(s) -> backward reshape */

	/* Change layout and/or chunk size */
	} else {
		/*
		 * Reshape layout (e.g. raid5_ls -> raid5_n) and/or chunk size:
		 *
		 * keeping number of disks and do layout change ->
		 *
		 * toggle reshape_backward depending on data_offset:
		 *
		 * - free space upfront -> reshape forward
		 *
		 * - free space at the end -> reshape backward
		 *
		 *
		 * This utilizes free reshape space avoiding the need
		 * for userspace to move (parts of) LV segments in
		 * case of layout/chunksize change  (for disk
		 * adding/removing reshape space has to be at
		 * the proper address (see above with delta_disks):
		 *
		 * add disk(s)   -> begin
		 * remove disk(s)-> end
		 */
		mddev->reshape_backwards = rs->dev[0].rdev.data_offset ? 0 : 1;
	}

	return r;
}

/*
 * Enable/disable discard support on RAID set depending on
 * RAID level and discard properties of underlying RAID members.
 */
static void configure_discard_support(struct raid_set *rs)
{
	int i;
	bool raid456;
	struct dm_target *ti = rs->ti;

	/* Assume discards not supported until after checks below. */
	ti->discards_supported = false;

	/* RAID level 4,5,6 require discard_zeroes_data for data integrity! */
	raid456 = (rs->md.level == 4 || rs->md.level == 5 || rs->md.level == 6);

	for (i = 0; i < rs->md.raid_disks; i++) {
		struct request_queue *q;

		if (!rs->dev[i].rdev.bdev)
			continue;

		q = bdev_get_queue(rs->dev[i].rdev.bdev);
		if (!q || !blk_queue_discard(q))
			return;

		if (raid456) {
			if (!q->limits.discard_zeroes_data)
				return;
			if (!devices_handle_discard_safely) {
				DMERR("raid456 discard support disabled due to discard_zeroes_data uncertainty.");
				DMERR("Set dm-raid.devices_handle_discard_safely=Y to override.");
				return;
			}
		}
	}

	/* All RAID members properly support discards */
	ti->discards_supported = true;

	/*
	 * RAID1 and RAID10 personalities require bio splitting,
	 * RAID0/4/5/6 don't and process large discard bios properly.
	 */
	ti->split_discard_bios = !!(rs->md.level == 1 || rs->md.level == 10);
	ti->num_discard_bios = 1;
}

/*
 * Construct a RAID0/1/10/4/5/6 mapping:
 * Args:
 *	<raid_type> <#raid_params> <raid_params>{0,}	\
 *	<#raid_devs> [<meta_dev1> <dev1>]{1,}
 *
 * <raid_params> varies by <raid_type>.	 See 'parse_raid_params' for
 * details on possible <raid_params>.
 *
 * Userspace is free to initialize the metadata devices, hence the superblocks to
 * enforce recreation based on the passed in table parameters.
 *
 */
static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv)
{
	int r;
	struct raid_type *rt;
	unsigned num_raid_params, num_raid_devs;
	struct raid_set *rs = NULL;
	const char *arg;
	struct rs_layout rs_layout;
	struct dm_arg_set as = { argc, argv }, as_nrd;
	struct dm_arg _args[] = {
		{ 0, as.argc, "Cannot understand number of raid parameters" },
		{ 1, 254, "Cannot understand number of raid devices parameters" }
	};

	/* Must have <raid_type> */
	arg = dm_shift_arg(&as);
	if (!arg) {
		ti->error = "No arguments";
		return -EINVAL;
	}

	rt = get_raid_type(arg);
	if (!rt) {
		ti->error = "Unrecognised raid_type";
		return -EINVAL;
	}

	/* Must have <#raid_params> */
	if (dm_read_arg_group(_args, &as, &num_raid_params, &ti->error))
		return -EINVAL;

	/* number of raid device tupples <meta_dev data_dev> */
	as_nrd = as;
	dm_consume_args(&as_nrd, num_raid_params);
	_args[1].max = (as_nrd.argc - 1) / 2;
	if (dm_read_arg(_args + 1, &as_nrd, &num_raid_devs, &ti->error))
		return -EINVAL;

	if (!__within_range(num_raid_devs, 1, MAX_RAID_DEVICES)) {
		ti->error = "Invalid number of supplied raid devices";
		return -EINVAL;
	}

	rs = raid_set_alloc(ti, rt, num_raid_devs);
	if (IS_ERR(rs))
		return PTR_ERR(rs);

	r = parse_raid_params(rs, &as, num_raid_params);
	if (r)
		goto bad;

	r = parse_dev_params(rs, &as);
	if (r)
		goto bad;

	rs->md.sync_super = super_sync;

	r = rs_set_dev_and_array_sectors(rs, false);
	if (r)
		return r;

	/*
	 * Backup any new raid set level, layout, ...
	 * requested to be able to compare to superblock
	 * members for conversion decisions.
	 */
	rs_config_backup(rs, &rs_layout);

	r = analyse_superblocks(ti, rs);
	if (r)
		goto bad;

	INIT_WORK(&rs->md.event_work, do_table_event);
	ti->private = rs;
	ti->num_flush_bios = 1;

	/* Restore any requested new layout for conversion decision */
	rs_config_restore(rs, &rs_layout);

	if (test_bit(MD_ARRAY_FIRST_USE, &rs->md.flags)) {
		set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags);
		rs_set_new(rs);
	} else if (rs_is_reshaping(rs))
		; /* skip rs setup */
	else if (rs_takeover_requested(rs)) {
		if (rs_is_reshaping(rs)) {
			ti->error = "Can't takeover a reshaping raid set";
			return -EPERM;
		}

		/*
		 * If a takeover is needed, just set the level to
		 * the new requested one and allow the raid set to run.
		 */
		r = rs_check_takeover(rs);
		if (r)
			return r;

		r = rs_setup_takeover(rs);
		if (r)
			return r;

		set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags);
		set_bit(RT_FLAG_KEEP_RS_FROZEN, &rs->runtime_flags);
		rs_set_new(rs);
	} else if (rs_reshape_requested(rs)) {
		if (rs_is_reshaping(rs)) {
			ti->error = "raid set already reshaping!";
			return -EPERM;
		}

		if (rs_is_raid10(rs)) {
			if (rs->raid_disks != rs->md.raid_disks &&
			    __is_raid10_near(rs->md.layout) &&
			    rs->raid10_copies &&
			    rs->raid10_copies != __raid10_near_copies(rs->md.layout)) {
				/*
				 * raid disk have to be multiple of data copies to allow this conversion,
				 *
				 * This is actually not a reshape it is a
				 * rebuild of any additional mirrors per group
				 */
				if (rs->raid_disks % rs->raid10_copies) {
					ti->error = "Can't reshape raid10 mirror groups";
					return -EINVAL;
				}

				/* Userpace reordered disks to add/remove mirrors -> adjust raid_disk indexes */
				__reorder_raid_disk_indexes(rs);
				rs->md.layout = raid10_format_to_md_layout(rs, ALGORITHM_RAID10_NEAR,
									   rs->raid10_copies);
				rs->md.new_layout = rs->md.layout;

			} else
				set_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags);

		} else if (rs_is_raid456(rs))
			set_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags);

		/*
		 * HM FIXME: process raid1 via delta_disks as well?
		 *           Would cause allocations in raid1->check_reshape
		 *           though, thus more issues with potential failures
		 */
		else if (rs_is_raid1(rs)) {
			set_bit(RT_FLAG_KEEP_RS_FROZEN, &rs->runtime_flags);
			rs->md.raid_disks = rs->raid_disks;
		}

		if (test_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags)) {
			set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags);
			set_bit(RT_FLAG_KEEP_RS_FROZEN, &rs->runtime_flags);
		}

		if (rs->md.raid_disks < rs->raid_disks)
			set_bit(MD_ARRAY_FIRST_USE, &rs->md.flags);

		rs_set_cur(rs);
	} else
		rs_set_cur(rs);

	/* If constructor requested it, change data and new_data offsets */
	r = rs_adjust_data_offsets(rs);
	if (r)
		return r;

	/* Start raid set read-only and assumed clean to change in raid_resume() */
	rs->md.ro = 1;
	rs->md.in_sync = 1;
	set_bit(MD_RECOVERY_FROZEN, &rs->md.recovery);

	/* Has to be held on running the array */
	mddev_lock_nointr(&rs->md);
	r = md_run(&rs->md);
	rs->md.in_sync = 0; /* Assume already marked dirty */

	if (r) {
		ti->error = "Failed to run raid array";
		mddev_unlock(&rs->md);
		goto bad;
	}

	rs->callbacks.congested_fn = raid_is_congested;
	dm_table_add_target_callbacks(ti->table, &rs->callbacks);

	mddev_suspend(&rs->md);

	/* Try to adjust the raid4/5/6 stripe cache size to the stripe size */
	if (rs_is_raid456(rs)) {
		r = rs_set_raid456_stripe_cache(rs);
		if (r)
			goto bad_stripe_cache;
	}

	/* Now do an early reshape check */
	if (test_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags)) {
		r = rs_check_reshape(rs);
		if (r)
			return r;

		/* Restore new, ctr requested layout to perform check */
		rs_config_restore(rs, &rs_layout);

		r = rs->md.pers->check_reshape(&rs->md);
		if (r) {
			ti->error = "Reshape check failed";
			goto bad_check_reshape;
		}
	}

	mddev_unlock(&rs->md);
	return 0;

bad_stripe_cache:
bad_check_reshape:
	md_stop(&rs->md);
bad:
	raid_set_free(rs);

	return r;
}

static void raid_dtr(struct dm_target *ti)
{
	struct raid_set *rs = ti->private;

	list_del_init(&rs->callbacks.list);
	md_stop(&rs->md);
	raid_set_free(rs);
}

static int raid_map(struct dm_target *ti, struct bio *bio)
{
	struct raid_set *rs = ti->private;
	struct mddev *mddev = &rs->md;

	/*
	 * If we're reshaping to add disk(s)), ti->len and
	 * mddev->array_sectors will differ during the process
	 * (ti->len > mddev->array_sectors), so we have to requeue
	 * bios with addresses > mddev->array_sectors here or
	 * or there will occur accesses past EOD of the component
	 * data images thus erroring the raid set.
	 */
	if (unlikely(bio_end_sector(bio) > mddev->array_sectors))
		return DM_MAPIO_REQUEUE;

	mddev->pers->make_request(mddev, bio);

	return DM_MAPIO_SUBMITTED;
}

/* Return string describing the current sync action of @mddev */
static const char *decipher_sync_action(struct mddev *mddev)
{
	if (test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))
		return "frozen";

	if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
	    (!mddev->ro && test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))) {
		if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
			return "reshape";

		if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
			if (!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
				return "resync";
			else if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
				return "check";
			return "repair";
		}

		if (test_bit(MD_RECOVERY_RECOVER, &mddev->recovery))
			return "recover";
	}

	return "idle";
}

/*
 * Return status string @rdev
 *
 * Status characters:
 *
 *  'D' = Dead/Failed device
 *  'a' = Alive but not in-sync
 *  'A' = Alive and in-sync
 */
static const char *__raid_dev_status(struct md_rdev *rdev, bool array_in_sync)
{
	if (test_bit(Faulty, &rdev->flags))
		return "D";
	else if (!array_in_sync || !test_bit(In_sync, &rdev->flags))
		return "a";
	else
		return "A";
}

/* Helper to return resync/reshape progress for @rs and @array_in_sync */
static sector_t rs_get_progress(struct raid_set *rs,
				sector_t resync_max_sectors, bool *array_in_sync)
{
	sector_t r, recovery_cp, curr_resync_completed;
	struct mddev *mddev = &rs->md;

	curr_resync_completed = mddev->curr_resync_completed ?: mddev->recovery_cp;
	recovery_cp = mddev->recovery_cp;
	*array_in_sync = false;

	if (rs_is_raid0(rs)) {
		r = resync_max_sectors;
		*array_in_sync = true;

	} else {
		r = mddev->reshape_position;

		/* Reshape is relative to the array size */
		if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) ||
		    r != MaxSector) {
			if (r == MaxSector) {
				*array_in_sync = true;
				r = resync_max_sectors;
			} else {
				/* Got to reverse on backward reshape */
				if (mddev->reshape_backwards)
					r = mddev->array_sectors - r;

				/* Devide by # of data stripes */
				sector_div(r, mddev_data_stripes(rs));
			}

		/* Sync is relative to the component device size */
		} else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
			r = curr_resync_completed;
		else
			r = recovery_cp;

		if (r == MaxSector) {
			/*
			 * Sync complete.
			 */
			*array_in_sync = true;
			r = resync_max_sectors;
		} else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
			/*
			 * If "check" or "repair" is occurring, the raid set has
			 * undergone an initial sync and the health characters
			 * should not be 'a' anymore.
			 */
			*array_in_sync = true;
		} else {
			struct md_rdev *rdev;

			/*
			 * The raid set may be doing an initial sync, or it may
			 * be rebuilding individual components.	 If all the
			 * devices are In_sync, then it is the raid set that is
			 * being initialized.
			 */
			rdev_for_each(rdev, mddev)
				if (!test_bit(In_sync, &rdev->flags))
					*array_in_sync = true;
#if 0
			r = 0; /* HM FIXME: TESTME: https://bugzilla.redhat.com/show_bug.cgi?id=1210637 ? */
#endif
		}
	}

	return r;
}

/* Helper to return @dev name or "-" if !@dev */
static const char *__get_dev_name(struct dm_dev *dev)
{
	return dev ? dev->name : "-";
}

static void raid_status(struct dm_target *ti, status_type_t type,
			unsigned int status_flags, char *result, unsigned int maxlen)
{
	struct raid_set *rs = ti->private;
	struct mddev *mddev = &rs->md;
	struct r5conf *conf = mddev->private;
	int max_nr_stripes = conf ? conf->max_nr_stripes : 0;
	bool array_in_sync;
	unsigned int raid_param_cnt = 1; /* at least 1 for chunksize */
	unsigned int sz = 0;
	unsigned int write_mostly_params = 0;
	sector_t progress, resync_max_sectors, resync_mismatches;
	const char *sync_action;
	struct raid_type *rt;
	struct md_rdev *rdev;

	switch (type) {
	case STATUSTYPE_INFO:
		/* *Should* always succeed */
		rt = get_raid_type_by_ll(mddev->new_level, mddev->new_layout);
		if (!rt)
			return;

		DMEMIT("%s %d ", rt->name, mddev->raid_disks);

		/* Access most recent mddev properties for status output */
		smp_rmb();
		/* Get sensible max sectors even if raid set not yet started */
		resync_max_sectors = test_bit(RT_FLAG_RS_PRERESUMED, &rs->runtime_flags) ?
				      mddev->resync_max_sectors : mddev->dev_sectors;
		progress = rs_get_progress(rs, resync_max_sectors, &array_in_sync);
		resync_mismatches = (mddev->last_sync_action && !strcasecmp(mddev->last_sync_action, "check")) ?
				    atomic64_read(&mddev->resync_mismatches) : 0;
		sync_action = decipher_sync_action(&rs->md);

		/* HM FIXME: do we want another state char for raid0? It shows 'D' or 'A' now */
		rdev_for_each(rdev, mddev)
			DMEMIT(__raid_dev_status(rdev, array_in_sync));

		/*
		 * In-sync/Reshape ratio:
		 *  The in-sync ratio shows the progress of:
		 *   - Initializing the raid set
		 *   - Rebuilding a subset of devices of the raid set
		 *  The user can distinguish between the two by referring
		 *  to the status characters.
		 *
		 *  The reshape ratio shows the progress of
		 *  changing the raid layout or the number of
		 *  disks of a raid set
		 */
		DMEMIT(" %llu/%llu", (unsigned long long) progress,
				     (unsigned long long) resync_max_sectors);

		/*
		 * v1.5.0+:
		 *
		 * Sync action:
		 *   See Documentation/device-mapper/dm-raid.txt for
		 *   information on each of these states.
		 */
		DMEMIT(" %s", sync_action);

		/*
		 * v1.5.0+:
		 *
		 * resync_mismatches/mismatch_cnt
		 *   This field shows the number of discrepancies found when
		 *   performing a "check" of the raid set.
		 */
		DMEMIT(" %llu", (unsigned long long) resync_mismatches);

		/*
		 * v1.9.0+:
		 *
		 * data_offset (needed for out of space reshaping)
		 *   This field shows the data offset into the data
		 *   image LV where the first stripes data starts.
		 *
		 * We keep data_offset equal on all raid disks of the set,
		 * so retrieving it from the first raid disk is sufficient.
		 */
		DMEMIT(" %llu", (unsigned long long) rs->dev[0].rdev.data_offset);
		break;

	case STATUSTYPE_TABLE:
		/* Report the table line string you would use to construct this raid set */

		/* Calculate raid parameter count */
		rdev_for_each(rdev, mddev)
			if (test_bit(WriteMostly, &rdev->flags))
				write_mostly_params += 2;
		raid_param_cnt += memweight(rs->rebuild_disks,
					    DISKS_ARRAY_ELEMS * sizeof(*rs->rebuild_disks)) * 2 +
				  write_mostly_params +
				  hweight32(rs->ctr_flags & CTR_FLAG_OPTIONS_NO_ARGS) +
				  hweight32(rs->ctr_flags & CTR_FLAG_OPTIONS_ONE_ARG) * 2;
		/* Emit table line */
		DMEMIT("%s %u %u", rs->raid_type->name, raid_param_cnt, mddev->new_chunk_sectors);
		if (test_bit(__CTR_FLAG_RAID10_FORMAT, &rs->ctr_flags))
			DMEMIT(" %s %s", dm_raid_arg_name_by_flag(CTR_FLAG_RAID10_FORMAT),
					 raid10_md_layout_to_format(mddev->layout));
		if (test_bit(__CTR_FLAG_RAID10_COPIES, &rs->ctr_flags))
			DMEMIT(" %s %d", dm_raid_arg_name_by_flag(CTR_FLAG_RAID10_COPIES),
					 raid10_md_layout_to_copies(mddev->layout));
		if (test_bit(__CTR_FLAG_NOSYNC, &rs->ctr_flags))
			DMEMIT(" %s", dm_raid_arg_name_by_flag(CTR_FLAG_NOSYNC));
		if (test_bit(__CTR_FLAG_SYNC, &rs->ctr_flags))
			DMEMIT(" %s", dm_raid_arg_name_by_flag(CTR_FLAG_SYNC));
		if (test_bit(__CTR_FLAG_REGION_SIZE, &rs->ctr_flags))
			DMEMIT(" %s %llu", dm_raid_arg_name_by_flag(CTR_FLAG_REGION_SIZE),
					   (unsigned long long) to_sector(mddev->bitmap_info.chunksize));
		if (test_bit(__CTR_FLAG_DATA_OFFSET, &rs->ctr_flags))
			DMEMIT(" %s %llu", dm_raid_arg_name_by_flag(CTR_FLAG_DATA_OFFSET),
					   (unsigned long long) rs->data_offset);
		if (test_bit(__CTR_FLAG_DAEMON_SLEEP, &rs->ctr_flags))
			DMEMIT(" %s %lu", dm_raid_arg_name_by_flag(CTR_FLAG_DAEMON_SLEEP),
					  mddev->bitmap_info.daemon_sleep);
		if (test_bit(__CTR_FLAG_DELTA_DISKS, &rs->ctr_flags))
			DMEMIT(" %s %d", dm_raid_arg_name_by_flag(CTR_FLAG_DELTA_DISKS),
					 mddev->delta_disks);
		if (test_bit(__CTR_FLAG_STRIPE_CACHE, &rs->ctr_flags))
			DMEMIT(" %s %d", dm_raid_arg_name_by_flag(CTR_FLAG_STRIPE_CACHE),
					 max_nr_stripes);
		rdev_for_each(rdev, mddev)
			if (test_bit(rdev->raid_disk, (void *) rs->rebuild_disks))
				DMEMIT(" %s %u", dm_raid_arg_name_by_flag(CTR_FLAG_REBUILD),
						 rdev->raid_disk);
		rdev_for_each(rdev, mddev)
			if (test_bit(WriteMostly, &rdev->flags))
				DMEMIT(" %s %d", dm_raid_arg_name_by_flag(CTR_FLAG_WRITE_MOSTLY),
						 rdev->raid_disk);
		if (test_bit(__CTR_FLAG_MAX_WRITE_BEHIND, &rs->ctr_flags))
			DMEMIT(" %s %lu", dm_raid_arg_name_by_flag(CTR_FLAG_MAX_WRITE_BEHIND),
					  mddev->bitmap_info.max_write_behind);
		if (test_bit(__CTR_FLAG_MAX_RECOVERY_RATE, &rs->ctr_flags))
			DMEMIT(" %s %d", dm_raid_arg_name_by_flag(CTR_FLAG_MAX_RECOVERY_RATE),
					 mddev->sync_speed_max);
		if (test_bit(__CTR_FLAG_MIN_RECOVERY_RATE, &rs->ctr_flags))
			DMEMIT(" %s %d", dm_raid_arg_name_by_flag(CTR_FLAG_MIN_RECOVERY_RATE),
					 mddev->sync_speed_min);
		DMEMIT(" %d", rs->raid_disks);
		rdev_for_each(rdev, mddev) {
			struct raid_dev *rd = container_of(rdev, struct raid_dev, rdev);

			DMEMIT(" %s %s", __get_dev_name(rd->meta_dev),
					 __get_dev_name(rd->data_dev));
		}
	}
}

static int raid_message(struct dm_target *ti, unsigned argc, char **argv)
{
	struct raid_set *rs = ti->private;
	struct mddev *mddev = &rs->md;

	if (!mddev->pers || !mddev->pers->sync_request)
		return -EINVAL;

	if (!strcasecmp(argv[0], "frozen"))
		set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
	else
		clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);

	if (!strcasecmp(argv[0], "idle") || !strcasecmp(argv[0], "frozen")) {
		if (mddev->sync_thread) {
			set_bit(MD_RECOVERY_INTR, &mddev->recovery);
			md_reap_sync_thread(mddev);
		}
	} else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
		   test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
		return -EBUSY;
	else if (!strcasecmp(argv[0], "resync"))
		; /* MD_RECOVERY_NEEDED set below */
	else if (!strcasecmp(argv[0], "recover"))
		set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
	else {
		if (!strcasecmp(argv[0], "check"))
			set_bit(MD_RECOVERY_CHECK, &mddev->recovery);
		else if (!!strcasecmp(argv[0], "repair"))
			return -EINVAL;
		set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
		set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
	}
	if (mddev->ro == 2) {
		/* A write to sync_action is enough to justify
		 * canceling read-auto mode
		 */
		mddev->ro = 0;
		if (!mddev->suspended && mddev->sync_thread)
			md_wakeup_thread(mddev->sync_thread);
	}
	set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
	if (!mddev->suspended && mddev->thread)
		md_wakeup_thread(mddev->thread);

	return 0;
}

static int raid_iterate_devices(struct dm_target *ti,
				iterate_devices_callout_fn fn, void *data)
{
	struct raid_set *rs = ti->private;
	unsigned i;
	int r = 0;

	for (i = 0; !r && i < rs->md.raid_disks; i++)
		if (rs->dev[i].data_dev)
			r = fn(ti,
				 rs->dev[i].data_dev,
				 0, /* No offset on data devs */
				 rs->md.dev_sectors,
				 data);

	return r;
}

static void raid_io_hints(struct dm_target *ti, struct queue_limits *limits)
{
	struct raid_set *rs = ti->private;
	unsigned chunk_size = rs->md.chunk_sectors << 9;
	struct r5conf *conf = rs->md.private;

	blk_limits_io_min(limits, chunk_size);
	blk_limits_io_opt(limits, chunk_size * (conf->raid_disks - conf->max_degraded));
}

static void raid_presuspend(struct dm_target *ti)
{
	struct raid_set *rs = ti->private;

	md_stop_writes(&rs->md);
}

static void raid_postsuspend(struct dm_target *ti)
{
	struct raid_set *rs = ti->private;

	if (test_and_clear_bit(RT_FLAG_RS_RESUMED, &rs->runtime_flags)) {
		if (!rs->md.suspended)
			mddev_suspend(&rs->md);
		rs->md.ro = 1;
	}
}

static void attempt_restore_of_faulty_devices(struct raid_set *rs)
{
	int i;
	uint64_t failed_devices, cleared_failed_devices = 0;
	unsigned long flags;
	struct dm_raid_superblock *sb;
	struct md_rdev *r;

	for (i = 0; i < rs->md.raid_disks; i++) {
		r = &rs->dev[i].rdev;
		if (test_bit(Faulty, &r->flags) && r->sb_page &&
		    sync_page_io(r, 0, r->sb_size, r->sb_page, REQ_OP_READ, 0,
				 1)) {
			DMINFO("Faulty %s device #%d has readable super block."
			       "  Attempting to revive it.",
			       rs->raid_type->name, i);

			/*
			 * Faulty bit may be set, but sometimes the array can
			 * be suspended before the personalities can respond
			 * by removing the device from the array (i.e. calling
			 * 'hot_remove_disk').	If they haven't yet removed
			 * the failed device, its 'raid_disk' number will be
			 * '>= 0' - meaning we must call this function
			 * ourselves.
			 */
			if ((r->raid_disk >= 0) &&
			    (r->mddev->pers->hot_remove_disk(r->mddev, r) != 0))
				/* Failed to revive this device, try next */
				continue;

			r->raid_disk = i;
			r->saved_raid_disk = i;
			flags = r->flags;
			clear_bit(Faulty, &r->flags);
			clear_bit(WriteErrorSeen, &r->flags);
			clear_bit(In_sync, &r->flags);
			if (r->mddev->pers->hot_add_disk(r->mddev, r)) {
				r->raid_disk = -1;
				r->saved_raid_disk = -1;
				r->flags = flags;
			} else {
				r->recovery_offset = 0;
				cleared_failed_devices |= 1 << i;
			}
		}
	}
	if (cleared_failed_devices) {
		rdev_for_each(r, &rs->md) {
			sb = page_address(r->sb_page);
			failed_devices = le64_to_cpu(sb->failed_devices);
			failed_devices &= ~cleared_failed_devices;
			sb->failed_devices = cpu_to_le64(failed_devices);
		}
	}
}

static int __load_dirty_region_bitmap(struct raid_set *rs)
{
	int r = 0;

	/* Try loading the bitmap unless "raid0", which does not have one */
	if (!rs_is_raid0(rs) &&
	    !test_and_set_bit(RT_FLAG_RS_BITMAP_LOADED, &rs->runtime_flags)) {
		r = bitmap_load(&rs->md);
		if (r)
			DMERR("Failed to load bitmap");
	}

	return r;
}

/* Enforce updating all superblocks */
static void rs_update_sbs(struct raid_set *rs)
{
	struct mddev *mddev = &rs->md;
	int ro = mddev->ro;

	set_bit(MD_CHANGE_DEVS, &mddev->flags);
	mddev->ro = 0;
	md_update_sb(mddev, 1);
	mddev->ro = ro;
}

/*
 * Reshape changes raid algorithm of @rs to new one within personality
 * (e.g. raid6_zr -> raid6_nc), changes stripe size, adds/removes
 * disks from a raid set thus growing/shrinking it or resizes the set
 *
 * Call mddev_lock_nointr() before!
 */
static int rs_start_reshape(struct raid_set *rs)
{
	int r;
	struct mddev *mddev = &rs->md;
	struct md_personality *pers = mddev->pers;

	r = rs_setup_reshape(rs);
	if (r)
		return r;

	/* Need to be resumed to be able to start reshape, recovery is frozen until raid_resume() though */
	if (mddev->suspended)
		mddev_resume(mddev);

	/*
	 * Check any reshape constraints enforced by the personalility
	 *
	 * May as well already kick the reshape off so that * pers->start_reshape() becomes optional.
	 */
	r = pers->check_reshape(mddev);
	if (r) {
		rs->ti->error = "pers->check_reshape() failed";
		return r;
	}

	/*
	 * Personality may not provide start reshape method in which
	 * case check_reshape above has already covered everything
	 */
	if (pers->start_reshape) {
		r = pers->start_reshape(mddev);
		if (r) {
			rs->ti->error = "pers->start_reshape() failed";
			return r;
		}
	}

	/* Suspend because a resume will happen in raid_resume() */
	if (!mddev->suspended)
		mddev_suspend(mddev);

	/*
	 * Now reshape got set up, update superblocks to
	 * reflect the fact so that a table reload will
	 * access proper superblock content in the ctr.
	 */
	rs_update_sbs(rs);

	return 0;
}

static int raid_preresume(struct dm_target *ti)
{
	int r;
	struct raid_set *rs = ti->private;
	struct mddev *mddev = &rs->md;

	/* This is a resume after a suspend of the set -> it's already started */
	if (test_and_set_bit(RT_FLAG_RS_PRERESUMED, &rs->runtime_flags))
		return 0;

	/*
	 * The superblocks need to be updated on disk if the
	 * array is new or new devices got added (thus zeroed
	 * out by userspace) or __load_dirty_region_bitmap
	 * will overwrite them in core with old data or fail.
	 */
	if (test_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags))
		rs_update_sbs(rs);

	/*
	 * Disable/enable discard support on raid set after any
	 * conversion, because devices can have been added
	 */
	configure_discard_support(rs);

	/* Load the bitmap from disk unless raid0 */
	r = __load_dirty_region_bitmap(rs);
	if (r)
		return r;

	/* Resize bitmap to adjust to changed region size (aka MD bitmap chunksize) */
	if (test_bit(RT_FLAG_RS_BITMAP_LOADED, &rs->runtime_flags) &&
	    mddev->bitmap_info.chunksize != to_bytes(rs->requested_bitmap_chunk_sectors)) {
		r = bitmap_resize(mddev->bitmap, mddev->dev_sectors,
				  to_bytes(rs->requested_bitmap_chunk_sectors), 0);
		if (r)
			DMERR("Failed to resize bitmap");
	}

	/* Check for any resize/reshape on @rs and adjust/initiate */
	/* Be prepared for mddev_resume() in raid_resume() */
	set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
	if (mddev->recovery_cp && mddev->recovery_cp < MaxSector) {
		set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
		set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
		mddev->resync_min = mddev->recovery_cp;
	}

	rs_set_capacity(rs);

	/* Check for any reshape request and region size change unless new raid set */
	if (test_and_clear_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags)) {
		/* Initiate a reshape. */
		mddev_lock_nointr(mddev);
		r = rs_start_reshape(rs);
		mddev_unlock(mddev);
		if (r)
			DMWARN("Failed to check/start reshape, continuing without change");
		r = 0;
	}

	return r;
}

static void raid_resume(struct dm_target *ti)
{
	struct raid_set *rs = ti->private;
	struct mddev *mddev = &rs->md;

	if (test_and_set_bit(RT_FLAG_RS_RESUMED, &rs->runtime_flags)) {
		/*
		 * A secondary resume while the device is active.
		 * Take this opportunity to check whether any failed
		 * devices are reachable again.
		 */
		attempt_restore_of_faulty_devices(rs);
	} else {
		mddev->ro = 0;
		mddev->in_sync = 0;

		/*
		 * When passing in flags to the ctr, we expect userspace
		 * to reset them because they made it to the superblocks
		 * and reload the mapping anyway.
		 *
		 * -> only unfreeze recovery in case of a table reload or
		 *    we'll have a bogus recovery/reshape position
		 *    retrieved from the superblock by the ctr because
		 *    the ongoing recovery/reshape will change it after read.
		 */
		if (!test_bit(RT_FLAG_KEEP_RS_FROZEN, &rs->runtime_flags))
			clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);

		if (mddev->suspended)
			mddev_resume(mddev);
	}
}

static struct target_type raid_target = {
	.name = "raid",
	.version = {1, 9, 0},
	.module = THIS_MODULE,
	.ctr = raid_ctr,
	.dtr = raid_dtr,
	.map = raid_map,
	.status = raid_status,
	.message = raid_message,
	.iterate_devices = raid_iterate_devices,
	.io_hints = raid_io_hints,
	.presuspend = raid_presuspend,
	.postsuspend = raid_postsuspend,
	.preresume = raid_preresume,
	.resume = raid_resume,
};

static int __init dm_raid_init(void)
{
	DMINFO("Loading target version %u.%u.%u",
	       raid_target.version[0],
	       raid_target.version[1],
	       raid_target.version[2]);
	return dm_register_target(&raid_target);
}

static void __exit dm_raid_exit(void)
{
	dm_unregister_target(&raid_target);
}

module_init(dm_raid_init);
module_exit(dm_raid_exit);

module_param(devices_handle_discard_safely, bool, 0644);
MODULE_PARM_DESC(devices_handle_discard_safely,
		 "Set to Y if all devices in each array reliably return zeroes on reads from discarded regions");

MODULE_DESCRIPTION(DM_NAME " raid0/1/10/4/5/6 target");
MODULE_ALIAS("dm-raid0");
MODULE_ALIAS("dm-raid1");
MODULE_ALIAS("dm-raid10");
MODULE_ALIAS("dm-raid4");
MODULE_ALIAS("dm-raid5");
MODULE_ALIAS("dm-raid6");
MODULE_AUTHOR("Neil Brown <dm-devel@redhat.com>");
MODULE_AUTHOR("Heinz Mauelshagen <dm-devel@redhat.com>");
MODULE_LICENSE("GPL");
