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

Commit b3546035 authored by NeilBrown's avatar NeilBrown
Browse files

md/raid5: allow layout/chunksize to be changed on an active 2-drive raid5.



2-drive raid5's aren't very interesting.  But if you are converting
a raid1 into a raid5, you will at least temporarily have one.  And
that it a good time to set the layout/chunksize for the new RAID5
if you aren't happy with the defaults.

layout and chunksize don't actually affect the placement of data
on a 2-drive raid5, so we just do some internal book-keeping.

Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent d562b0c4
Loading
Loading
Loading
Loading
+24 −13
Original line number Diff line number Diff line
@@ -2771,12 +2771,18 @@ layout_store(mddev_t *mddev, const char *buf, size_t len)
	if (!*buf || (*e && *e != '\n'))
		return -EINVAL;

	if (mddev->pers)
	if (mddev->pers) {
		int err;
		if (mddev->pers->reconfig == NULL)
			return -EBUSY;

		err = mddev->pers->reconfig(mddev, n, -1);
		if (err)
			return err;
	} else {
		mddev->new_layout = n;
		if (mddev->reshape_position == MaxSector)
			mddev->layout = n;
	}
	return len;
}
static struct md_sysfs_entry md_layout =
@@ -2833,19 +2839,24 @@ chunk_size_show(mddev_t *mddev, char *page)
static ssize_t
chunk_size_store(mddev_t *mddev, const char *buf, size_t len)
{
	/* can only set chunk_size if array is not yet active */
	char *e;
	unsigned long n = simple_strtoul(buf, &e, 10);

	if (!*buf || (*e && *e != '\n'))
		return -EINVAL;

	if (mddev->pers)
	if (mddev->pers) {
		int err;
		if (mddev->pers->reconfig == NULL)
			return -EBUSY;

		err = mddev->pers->reconfig(mddev, -1, n);
		if (err)
			return err;
	} else {
		mddev->new_chunk = n;
		if (mddev->reshape_position == MaxSector)
			mddev->chunk_size = n;
	}
	return len;
}
static struct md_sysfs_entry md_chunk_size =
+42 −0
Original line number Diff line number Diff line
@@ -4913,6 +4913,47 @@ static void *raid5_takeover_raid1(mddev_t *mddev)
}


static int raid5_reconfig(mddev_t *mddev, int new_layout, int new_chunk)
{
	/* Currently the layout and chunk size can only be changed
	 * for a 2-drive raid array, as in that case no data shuffling
	 * is required.
	 * Later we might validate these and set new_* so a reshape
	 * can complete the change.
	 */
	raid5_conf_t *conf = mddev_to_conf(mddev);

	if (new_layout >= 0 && !algorithm_valid_raid5(new_layout))
		return -EINVAL;
	if (new_chunk > 0) {
		if (new_chunk & (new_chunk-1))
			/* not a power of 2 */
			return -EINVAL;
		if (new_chunk < PAGE_SIZE)
			return -EINVAL;
		if (mddev->array_sectors & ((new_chunk>>9)-1))
			/* not factor of array size */
			return -EINVAL;
	}

	/* They look valid */

	if (mddev->raid_disks != 2)
		return -EINVAL;

	if (new_layout >= 0) {
		conf->algorithm = new_layout;
		mddev->layout = mddev->new_layout = new_layout;
	}
	if (new_chunk > 0) {
		conf->chunk_size = new_chunk;
		mddev->chunk_size = mddev->new_chunk = new_chunk;
	}
	set_bit(MD_CHANGE_DEVS, &mddev->flags);
	md_wakeup_thread(mddev->thread);
	return 0;
}

static void *raid5_takeover(mddev_t *mddev)
{
	/* raid5 can take over:
@@ -5023,6 +5064,7 @@ static struct mdk_personality raid5_personality =
#endif
	.quiesce	= raid5_quiesce,
	.takeover	= raid5_takeover,
	.reconfig	= raid5_reconfig,
};

static struct mdk_personality raid4_personality =