From dfe77a9ed2436f59e9ca35870102e2b18e4939d3 Mon Sep 17 00:00:00 2001 From: Krzysztof Wojcik Date: Thu, 27 Jan 2011 08:42:41 +1100 Subject: [PATCH] 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 Signed-off-by: NeilBrown --- Grow.c | 39 ++++++++++++++++++++++++++++----------- super-intel.c | 6 ++++++ 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; -- 2.39.2