summaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2009-03-31 05:56:41 +0200
committerNeilBrown <neilb@suse.de>2009-03-31 05:56:41 +0200
commitb3546035277847028df650b147469fc943cf5c71 (patch)
tree87966abc5456a62845326eb8d5a5cf0f88879b2d /drivers/md/raid5.c
parentmd: add ->takeover method for raid5 to be able to take over raid1 (diff)
downloadlinux-b3546035277847028df650b147469fc943cf5c71.tar.xz
linux-b3546035277847028df650b147469fc943cf5c71.zip
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>
Diffstat (limited to '')
-rw-r--r--drivers/md/raid5.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 611ea7bbf474..8a5e14e4a851 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -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 =