summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrzysztof Wojcik <krzysztof.wojcik@intel.com>2011-01-27 08:42:41 +1100
committerNeilBrown <neilb@suse.de>2011-01-27 12:47:15 +1000
commitdfe77a9ed2436f59e9ca35870102e2b18e4939d3 (patch)
tree18b85a7083acb87af6404af4166b6cae0e457634
parent26d6e1574a1673d98a4cdd5a76d9c6f7de72e9d4 (diff)
Add raid1->raid0 takeover support
Add support for raid1 to raid0 takeover operation in user space. This patch includes support for native and imsm metadata. Signed-off-by: Krzysztof Wojcik <krzysztof.wojcik@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--Grow.c39
-rw-r--r--super-intel.c6
2 files changed, 34 insertions, 11 deletions
diff --git a/Grow.c b/Grow.c
index b14d6381..cd044bf6 100644
--- a/Grow.c
+++ b/Grow.c
@@ -653,15 +653,20 @@ void abort_reshape(struct mdinfo *sra)
sysfs_set_str(sra, NULL, "sync_max", "max");
}
-int remove_disks_on_raid10_to_raid0_takeover(struct supertype *st,
- struct mdinfo *sra,
- int layout)
+int remove_disks_for_takeover(struct supertype *st,
+ struct mdinfo *sra,
+ int layout)
{
int nr_of_copies;
struct mdinfo *remaining;
int slot;
- nr_of_copies = layout & 0xff;
+ if (sra->array.level == 10)
+ nr_of_copies = layout & 0xff;
+ else if (sra->array.level == 1)
+ nr_of_copies = sra->array.raid_disks;
+ else
+ return 1;
remaining = sra->devs;
sra->devs = NULL;
@@ -913,8 +918,18 @@ char *analyse_change(struct mdinfo *info, struct reshape *re)
switch (info->array.level) {
case 1:
/* RAID1 can convert to RAID1 with different disks, or
- * raid5 with 2 disks
+ * raid5 with 2 disks, or
+ * raid0 with 1 disk
*/
+ if (info->new_level == 0) {
+ re->level = 0;
+ re->before.data_disks = 1;
+ re->after.data_disks = 1;
+ re->before.layout = 0;
+ re->backup_blocks = 0;
+ re->parity = 0;
+ return NULL;
+ }
if (info->new_level == 1) {
if (info->delta_disks == UnSet)
/* Don't know what to do */
@@ -1450,15 +1465,17 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
size = array.size;
}
- /* ========= check for Raid10 -> Raid0 conversion ===============
+ /* ========= check for Raid10/Raid1 -> Raid0 conversion ===============
* current implementation assumes that following conditions must be met:
- * - far_copies == 1
- * - near_copies == 2
+ * - RAID10:
+ * - far_copies == 1
+ * - near_copies == 2
*/
- if (level == 0 && array.level == 10 && sra &&
- array.layout == ((1 << 8) + 2) && !(array.raid_disks & 1)) {
+ if ((level == 0 && array.level == 10 && sra &&
+ array.layout == ((1 << 8) + 2) && !(array.raid_disks & 1)) ||
+ (level == 0 && array.level == 1 && sra)) {
int err;
- err = remove_disks_on_raid10_to_raid0_takeover(st, sra, array.layout);
+ err = remove_disks_for_takeover(st, sra, array.layout);
if (err) {
dprintf(Name": Array cannot be reshaped\n");
if (cfd > -1)
diff --git a/super-intel.c b/super-intel.c
index 8d1f0ada..8e999a5f 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -6916,6 +6916,12 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
check_devs = 1;
}
break;
+ case 1:
+ if (geo->level == 0) {
+ change = CH_TAKEOVER;
+ check_devs = 1;
+ }
+ break;
case 5:
if (geo->level != 0)
change = CH_LEVEL_MIGRATION;