linux-raid.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: NeilBrown <neilb@suse.de>
To: linux-raid@vger.kernel.org
Cc: NeilBrown <neilb@suse.de>
Subject: [md PATCH 09/14] md/raid5: allow layout and chunksize to be changed on active array.
Date: Tue, 31 Mar 2009 15:54:43 +1100	[thread overview]
Message-ID: <20090331045443.2589.66653.stgit@notabene.brown> (raw)
In-Reply-To: <20090331044827.2589.95894.stgit@notabene.brown>

If an array has 3 or more devices, we allow the chunksize or layout
to be changed and when a reshape starts, we use these as the 'new'
values.


Signed-off-by: NeilBrown <neilb@suse.de>
---

 drivers/md/raid5.c |   76 ++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 56 insertions(+), 20 deletions(-)

diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index f7fb2b8..4fdc6d0 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -4397,9 +4397,7 @@ static int run(mddev_t *mddev)
 		int old_disks;
 		int max_degraded = (mddev->level == 6 ? 2 : 1);
 
-		if (mddev->new_level != mddev->level ||
-		    mddev->new_layout != mddev->layout ||
-		    mddev->new_chunk != mddev->chunk_size) {
+		if (mddev->new_level != mddev->level) {
 			printk(KERN_ERR "raid5: %s: unsupported reshape "
 			       "required - aborting.\n",
 			       mdname(mddev));
@@ -4784,8 +4782,10 @@ static int raid5_check_reshape(mddev_t *mddev)
 {
 	raid5_conf_t *conf = mddev_to_conf(mddev);
 
-	if (mddev->delta_disks == 0)
-		return 0; /* nothing to do */
+	if (mddev->delta_disks == 0 &&
+	    mddev->new_layout == mddev->layout &&
+	    mddev->new_chunk == mddev->chunk_size)
+		return -EINVAL; /* nothing to do */
 	if (mddev->bitmap)
 		/* Cannot grow a bitmap yet */
 		return -EBUSY;
@@ -4860,6 +4860,10 @@ static int raid5_start_reshape(mddev_t *mddev)
 	spin_lock_irq(&conf->device_lock);
 	conf->previous_raid_disks = conf->raid_disks;
 	conf->raid_disks += mddev->delta_disks;
+	conf->prev_chunk = conf->chunk_size;
+	conf->chunk_size = mddev->new_chunk;
+	conf->prev_algo = conf->algorithm;
+	conf->algorithm = mddev->new_layout;
 	if (mddev->delta_disks < 0)
 		conf->reshape_progress = raid5_size(mddev, 0, 0);
 	else
@@ -4952,6 +4956,7 @@ static void end_reshape(raid5_conf_t *conf)
 static void raid5_finish_reshape(mddev_t *mddev)
 {
 	struct block_device *bdev;
+	raid5_conf_t *conf = mddev_to_conf(mddev);
 
 	if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
 
@@ -4970,7 +4975,6 @@ static void raid5_finish_reshape(mddev_t *mddev)
 			}
 		} else {
 			int d;
-			raid5_conf_t *conf = mddev_to_conf(mddev);
 			mddev->degraded = conf->raid_disks;
 			for (d = 0; d < conf->raid_disks ; d++)
 				if (conf->disks[d].rdev &&
@@ -4982,6 +4986,8 @@ static void raid5_finish_reshape(mddev_t *mddev)
 			     d++)
 				raid5_remove_disk(mddev, d);
 		}
+		mddev->layout = conf->algorithm;
+		mddev->chunk_size = conf->chunk_size;
 		mddev->reshape_position = MaxSector;
 		mddev->delta_disks = 0;
 	}
@@ -5080,11 +5086,10 @@ static void *raid5_takeover_raid6(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.
+	/* For a 2-drive array, the layout and chunk size can be changed
+	 * immediately as not restriping is needed.
+	 * For larger arrays we record the new value - after validation
+	 * to be used by a reshape pass.
 	 */
 	raid5_conf_t *conf = mddev_to_conf(mddev);
 
@@ -5103,19 +5108,49 @@ static int raid5_reconfig(mddev_t *mddev, int new_layout, int new_chunk)
 
 	/* They look valid */
 
-	if (mddev->raid_disks != 2)
-		return -EINVAL;
+	if (mddev->raid_disks == 2) {
 
-	if (new_layout >= 0) {
-		conf->algorithm = new_layout;
-		mddev->layout = mddev->new_layout = new_layout;
+		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);
+	} else {
+		if (new_layout >= 0)
+			mddev->new_layout = new_layout;
+		if (new_chunk > 0)
+			mddev->new_chunk = new_chunk;
 	}
+	return 0;
+}
+
+static int raid6_reconfig(mddev_t *mddev, int new_layout, int new_chunk)
+{
+	if (new_layout >= 0 && !algorithm_valid_raid6(new_layout))
+		return -EINVAL;
 	if (new_chunk > 0) {
-		conf->chunk_size = new_chunk;
-		mddev->chunk_size = mddev->new_chunk = new_chunk;
+		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;
 	}
-	set_bit(MD_CHANGE_DEVS, &mddev->flags);
-	md_wakeup_thread(mddev->thread);
+
+	/* They look valid */
+
+	if (new_layout >= 0)
+		mddev->new_layout = new_layout;
+	if (new_chunk > 0)
+		mddev->new_chunk = new_chunk;
+
 	return 0;
 }
 
@@ -5216,6 +5251,7 @@ static struct mdk_personality raid6_personality =
 #endif
 	.quiesce	= raid5_quiesce,
 	.takeover	= raid6_takeover,
+	.reconfig	= raid6_reconfig,
 };
 static struct mdk_personality raid5_personality =
 {



  parent reply	other threads:[~2009-03-31  4:54 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-31  4:54 [md PATCH 00/14] Final set of patches head for 2.6.30 NeilBrown
2009-03-31  4:54 ` [md PATCH 01/14] md: add explicit method to signal the end of a reshape NeilBrown
2009-03-31  4:54 ` [md PATCH 02/14] md/raid5: change reshape-progress measurement to cope with reshaping backwards NeilBrown
2009-03-31  4:54 ` NeilBrown [this message]
2009-03-31  4:54 ` [md PATCH 07/14] md/raid5: prepare for allowing reshape to change layout NeilBrown
2009-03-31  4:54 ` [md PATCH 08/14] md/raid5: reshape using largest of old and new chunk size NeilBrown
2009-03-31  4:54 ` [md PATCH 04/14] Documentation/md.txt update NeilBrown
2009-03-31  4:54 ` [md PATCH 03/14] md: allow number of drives in raid5 to be reduced NeilBrown
2009-03-31  4:54 ` [md PATCH 05/14] md/raid5: clearly differentiate 'before' and 'after' stripes during reshape NeilBrown
2009-03-31  4:54 ` [md PATCH 06/14] md/raid5: prepare for allowing reshape to change chunksize NeilBrown
2009-03-31  4:54 ` [md PATCH 12/14] md: remove CONFIG_MD_RAID_RESHAPE config option NeilBrown
2009-03-31  4:54 ` [md PATCH 10/14] md: don't display meaningless values in sysfs files resync_start and sync_speed NeilBrown
2009-03-31  4:54 ` [md PATCH 13/14] md/raid5: minor code cleanups in make_request NeilBrown
2009-03-31  4:54 ` [md PATCH 14/14] md/raid5 revise rules for when to update metadata during reshape NeilBrown
2009-03-31  4:54 ` [md PATCH 11/14] md/raid5: be more careful about write ordering when reshaping NeilBrown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090331045443.2589.66653.stgit@notabene.brown \
    --to=neilb@suse.de \
    --cc=linux-raid@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).