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: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
d562b0c431
commit
b354603527
@ -2771,12 +2771,18 @@ layout_store(mddev_t *mddev, const char *buf, size_t len)
|
|||||||
if (!*buf || (*e && *e != '\n'))
|
if (!*buf || (*e && *e != '\n'))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (mddev->pers)
|
if (mddev->pers) {
|
||||||
return -EBUSY;
|
int err;
|
||||||
|
if (mddev->pers->reconfig == NULL)
|
||||||
mddev->new_layout = n;
|
return -EBUSY;
|
||||||
if (mddev->reshape_position == MaxSector)
|
err = mddev->pers->reconfig(mddev, n, -1);
|
||||||
mddev->layout = n;
|
if (err)
|
||||||
|
return err;
|
||||||
|
} else {
|
||||||
|
mddev->new_layout = n;
|
||||||
|
if (mddev->reshape_position == MaxSector)
|
||||||
|
mddev->layout = n;
|
||||||
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
static struct md_sysfs_entry md_layout =
|
static struct md_sysfs_entry md_layout =
|
||||||
@ -2833,19 +2839,24 @@ chunk_size_show(mddev_t *mddev, char *page)
|
|||||||
static ssize_t
|
static ssize_t
|
||||||
chunk_size_store(mddev_t *mddev, const char *buf, size_t len)
|
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;
|
char *e;
|
||||||
unsigned long n = simple_strtoul(buf, &e, 10);
|
unsigned long n = simple_strtoul(buf, &e, 10);
|
||||||
|
|
||||||
if (!*buf || (*e && *e != '\n'))
|
if (!*buf || (*e && *e != '\n'))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (mddev->pers)
|
if (mddev->pers) {
|
||||||
return -EBUSY;
|
int err;
|
||||||
|
if (mddev->pers->reconfig == NULL)
|
||||||
mddev->new_chunk = n;
|
return -EBUSY;
|
||||||
if (mddev->reshape_position == MaxSector)
|
err = mddev->pers->reconfig(mddev, -1, n);
|
||||||
mddev->chunk_size = n;
|
if (err)
|
||||||
|
return err;
|
||||||
|
} else {
|
||||||
|
mddev->new_chunk = n;
|
||||||
|
if (mddev->reshape_position == MaxSector)
|
||||||
|
mddev->chunk_size = n;
|
||||||
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
static struct md_sysfs_entry md_chunk_size =
|
static struct md_sysfs_entry md_chunk_size =
|
||||||
|
@ -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)
|
static void *raid5_takeover(mddev_t *mddev)
|
||||||
{
|
{
|
||||||
/* raid5 can take over:
|
/* raid5 can take over:
|
||||||
@ -5023,6 +5064,7 @@ static struct mdk_personality raid5_personality =
|
|||||||
#endif
|
#endif
|
||||||
.quiesce = raid5_quiesce,
|
.quiesce = raid5_quiesce,
|
||||||
.takeover = raid5_takeover,
|
.takeover = raid5_takeover,
|
||||||
|
.reconfig = raid5_reconfig,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct mdk_personality raid4_personality =
|
static struct mdk_personality raid4_personality =
|
||||||
|
Loading…
Reference in New Issue
Block a user