* Subject: [PATCH 4/4] imsm: support for raid0 <-> raid5 migration
@ 2011-01-11 15:24 Labun, Marcin
2011-01-12 6:20 ` NeilBrown
0 siblings, 1 reply; 2+ messages in thread
From: Labun, Marcin @ 2011-01-11 15:24 UTC (permalink / raw)
To: neilb@suse.de
Cc: linux-raid@vger.kernel.org, Kwolek, Adam, Williams, Dan J,
Ciechanowski, Ed, Neubauer, Wojciech
From 218f21b2d6f55798ea7df2f82668fdf51f4b158a Mon Sep 17 00:00:00 2001
From: Marcin Labun <marcin.labun@intel.com>
Date: Tue, 11 Jan 2011 16:01:59 +0100
Subject: [PATCH 4/4] imsm: support for raid0 <-> raid5 migration
Support for raid0 to raid5 and raid5 to raid0 migration in imsm.
This is work in progress.
Signed-off-by: Marcin Labun <marcin.labun@intel.com>
---
super-intel.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 143 insertions(+), 4 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index d3da6f9..3a471c3 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -317,6 +317,9 @@ struct imsm_update_reshape {
enum imsm_update_type type;
int old_raid_disks;
int new_raid_disks;
+ int new_level;
+ int new_chunksize;
+ long long new_size;
int new_disks[1]; /* new_raid_disks - old_raid_disks makedev number */
};
@@ -5816,6 +5819,7 @@ static int apply_reshape_container_disks_update(struct imsm_update_reshape *u,
newdev->vol.curr_migr_unit = 0;
newdev->vol.migr_type = MIGR_GEN_MIGR;
newmap->num_members = u->new_raid_disks;
+ newmap->raid_level = u->new_level;
for (i = 0; i < delta_disks; i++) {
set_imsm_ord_tbl_ent(newmap,
u->old_raid_disks + i,
@@ -6421,6 +6425,18 @@ static int imsm_find_array_minor_by_subdev(int subdev, int container, int *minor
return 0;
}
+
+static int imsm_reshape_is_allowed_on_subarray(struct supertype *st,
+ struct geo_params *geo,
+ int *old_raid_disks)
+{
+ /* needs to convert requested geo to IMSM valid geometry
+ * all unset value shall be converted to current array values
+ */
+ dprintf("\tSub-array operation operation allowed\n");
+ return 1;
+}
+
static int imsm_reshape_is_allowed_on_container(struct supertype *st,
struct geo_params *geo,
int *old_raid_disks)
@@ -6569,12 +6585,14 @@ static int imsm_create_metadata_update_for_reshape(
u->type = update_reshape_container_disks;
u->old_raid_disks = old_raid_disks;
u->new_raid_disks = geo->raid_disks;
-
+ u->new_level = geo->level;
+ u->new_chunksize = geo->chunksize;
+ u->new_size = geo->size;
/* now get spare disks list
*/
spares = get_spares_for_grow(st);
- if (spares == NULL
+ if (((spares == NULL) && (delta_disks != 0))
|| delta_disks > spares->array.spare_disks) {
dprintf("imsm: ERROR: Cannot get spare devices.\n");
goto abort;
@@ -6618,6 +6636,75 @@ abort:
}
+static int allocate_space_list(struct intel_super *super, struct imsm_update_reshape *u, void ***space_list)
+{
+ /* Every raid device in the container is about to
+ * gain some more devices, and we will enter a
+ * reconfiguration.
+ * So each 'imsm_map' will be bigger, and the imsm_vol
+ * will now hold 2 of them.
+ * Thus we need new 'struct imsm_dev' allocations sized
+ * as sizeof_imsm_dev but with more devices in both maps.
+ */
+ struct intel_dev *dl;
+ void **space_tail = (void**)space_list;
+
+ dprintf("imsm: allocate_space_list() for update_reshape\n");
+
+ for (dl = super->devlist; dl; dl = dl->next) {
+ int size = sizeof_imsm_dev(dl->dev, 1);
+ void *s;
+ if (u->new_raid_disks > u->old_raid_disks)
+ size += sizeof(__u32)*2*
+ (u->new_raid_disks - u->old_raid_disks);
+ s = malloc(size);
+ if (!s)
+ return 1;
+ *space_tail = s;
+ space_tail = s;
+ *space_tail = NULL;
+ }
+ return 0;
+}
+
+// static int reallocate_anchor_for_update(struct intel_super *super, struct imsm_update_reshape *u);
+/*
+ * Check if there is enouht spare and reallocate anchor if neccessary
+ * Return:
+ * 1 - no enouth space for new request
+ * 0 - anchor ready for updates
+ */
+static int reallocate_anchor_for_update(struct intel_super *super, struct imsm_update_reshape *u)
+{
+ /* reallocate anchor
+ */
+ size_t buf_len = super->len;
+ size_t len = disks_to_mpb_size(u->new_raid_disks);
+ struct imsm_super *mpb = super->anchor;
+ void *new_anchor;
+
+ dprintf("imsm: realocate anchore\n");
+
+ if (__le32_to_cpu(mpb->mpb_size) + len > buf_len) {
+ buf_len = ROUND_UP(__le32_to_cpu(mpb->mpb_size) + len, 512);
+ if (posix_memalign(&new_anchor,
+ 512, buf_len) == 0) {
+ memcpy(new_anchor, super->buf, super->len);
+ free(super->buf);
+ super->buf = new_anchor;
+ super->len = buf_len;
+ } else
+ return 1;
+
+ }
+ return 0;
+}
+
+/*
+ * Reshape IMSM metadata - prepare metadata update
+ * 0 - update successfully reshaped
+ * 1 - reshape start failed - abort the process
+ */
static int imsm_reshape_super(struct supertype *st, long long size, int level,
int layout, int chunksize, int raid_disks,
char *backup, char *dev, int verbose)
@@ -6643,6 +6730,9 @@ static int imsm_reshape_super(struct supertype *st, long long size, int level,
dprintf("\tfor level : %i\n", geo.level);
dprintf("\tfor raid_disks : %i\n", geo.raid_disks);
+ dprintf("\tfor layout : %i\n", geo.layout);
+ dprintf("\tfor size : %llu\n", geo.size);
+ dprintf("\tfor chunksize : %i\n", geo.chunksize);
if (experimental() == 0)
return ret_val;
@@ -6734,8 +6824,57 @@ static int imsm_reshape_super(struct supertype *st, long long size, int level,
} else
fprintf(stderr, Name "imsm: Operation is not allowed "
"on this container\n");
- } else
- fprintf(stderr, Name "imsm: not a container operation\n");
+ } else {
+ struct imsm_update_reshape *u = NULL;
+ int len;
+ struct intel_super *super = st->sb;
+ void **space_list=NULL;
+
+ int old_raid_disks = 0;
+
+ dprintf("imsm: subarray reshape\n");
+ if (imsm_reshape_is_allowed_on_subarray(st, &geo, &old_raid_disks) == 0) {
+ dprintf("imsm: reshape not allowed\n");
+ goto exit_imsm_reshape_super;
+ }
+
+ len = imsm_create_metadata_update_for_reshape(st, &geo, old_raid_disks, &u);
+
+ if (len <= 0) {
+ dprintf("imsm: Cannot prepare update\n");
+ goto exit_imsm_reshape_super;
+ }
+
+ if (mdmon_running(st->container_dev)) {
+ ret_val = 0;
+ append_metadata_update(st, u, len);
+ goto exit_imsm_reshape_super;
+ }
+ /* no mdmon - apply update
+ */
+
+ dprintf("imsm:prepare space list for update_reshape\n");
+ ret_val = allocate_space_list(super, u, &space_list);
+ if (ret_val == 0) {
+ ret_val = apply_reshape_container_disks_update(u, super, &space_list);
+ /* processed if reshape applied */
+ if (ret_val == 1) {
+ ret_val = reallocate_anchor_for_update(super, u);
+ if (ret_val == 0)
+ super->updates_pending++;
+ }
+ else
+ /* set error code */
+ ret_val = 1;
+ }
+ /* release memory */
+ while (space_list) {
+ void *space = space_list;
+ space_list = *space_list;
+ free(space);
+ }
+ free(u);
+ }
exit_imsm_reshape_super:
dprintf("imsm: reshape_super Exit code = %i\n", ret_val);
--
1.6.4.2
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: Subject: [PATCH 4/4] imsm: support for raid0 <-> raid5 migration
2011-01-11 15:24 Subject: [PATCH 4/4] imsm: support for raid0 <-> raid5 migration Labun, Marcin
@ 2011-01-12 6:20 ` NeilBrown
0 siblings, 0 replies; 2+ messages in thread
From: NeilBrown @ 2011-01-12 6:20 UTC (permalink / raw)
To: Labun, Marcin
Cc: linux-raid@vger.kernel.org, Kwolek, Adam, Williams, Dan J,
Ciechanowski, Ed, Neubauer, Wojciech
On Tue, 11 Jan 2011 15:24:54 +0000 "Labun, Marcin" <Marcin.Labun@intel.com>
wrote:
> >From 218f21b2d6f55798ea7df2f82668fdf51f4b158a Mon Sep 17 00:00:00 2001
> From: Marcin Labun <marcin.labun@intel.com>
> Date: Tue, 11 Jan 2011 16:01:59 +0100
> Subject: [PATCH 4/4] imsm: support for raid0 <-> raid5 migration
>
> Support for raid0 to raid5 and raid5 to raid0 migration in imsm.
> This is work in progress.
This could usefully be broken up into smaller patches.
e.g. your 'allocate_space_list' contains code copied from imsm_prepare_update.
It would be better to have a single patch which moved that code into a
separate function, then another patch which uses the new function in the new
for the new functionality.
So: not applied.
NeilBrown
>
> Signed-off-by: Marcin Labun <marcin.labun@intel.com>
> ---
> super-intel.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 files changed, 143 insertions(+), 4 deletions(-)
>
> diff --git a/super-intel.c b/super-intel.c
> index d3da6f9..3a471c3 100644
> --- a/super-intel.c
> +++ b/super-intel.c
> @@ -317,6 +317,9 @@ struct imsm_update_reshape {
> enum imsm_update_type type;
> int old_raid_disks;
> int new_raid_disks;
> + int new_level;
> + int new_chunksize;
> + long long new_size;
> int new_disks[1]; /* new_raid_disks - old_raid_disks makedev number */
> };
>
> @@ -5816,6 +5819,7 @@ static int apply_reshape_container_disks_update(struct imsm_update_reshape *u,
> newdev->vol.curr_migr_unit = 0;
> newdev->vol.migr_type = MIGR_GEN_MIGR;
> newmap->num_members = u->new_raid_disks;
> + newmap->raid_level = u->new_level;
> for (i = 0; i < delta_disks; i++) {
> set_imsm_ord_tbl_ent(newmap,
> u->old_raid_disks + i,
> @@ -6421,6 +6425,18 @@ static int imsm_find_array_minor_by_subdev(int subdev, int container, int *minor
> return 0;
> }
>
> +
> +static int imsm_reshape_is_allowed_on_subarray(struct supertype *st,
> + struct geo_params *geo,
> + int *old_raid_disks)
> +{
> + /* needs to convert requested geo to IMSM valid geometry
> + * all unset value shall be converted to current array values
> + */
> + dprintf("\tSub-array operation operation allowed\n");
> + return 1;
> +}
> +
> static int imsm_reshape_is_allowed_on_container(struct supertype *st,
> struct geo_params *geo,
> int *old_raid_disks)
> @@ -6569,12 +6585,14 @@ static int imsm_create_metadata_update_for_reshape(
> u->type = update_reshape_container_disks;
> u->old_raid_disks = old_raid_disks;
> u->new_raid_disks = geo->raid_disks;
> -
> + u->new_level = geo->level;
> + u->new_chunksize = geo->chunksize;
> + u->new_size = geo->size;
> /* now get spare disks list
> */
> spares = get_spares_for_grow(st);
>
> - if (spares == NULL
> + if (((spares == NULL) && (delta_disks != 0))
> || delta_disks > spares->array.spare_disks) {
> dprintf("imsm: ERROR: Cannot get spare devices.\n");
> goto abort;
> @@ -6618,6 +6636,75 @@ abort:
> }
>
>
> +static int allocate_space_list(struct intel_super *super, struct imsm_update_reshape *u, void ***space_list)
> +{
> + /* Every raid device in the container is about to
> + * gain some more devices, and we will enter a
> + * reconfiguration.
> + * So each 'imsm_map' will be bigger, and the imsm_vol
> + * will now hold 2 of them.
> + * Thus we need new 'struct imsm_dev' allocations sized
> + * as sizeof_imsm_dev but with more devices in both maps.
> + */
> + struct intel_dev *dl;
> + void **space_tail = (void**)space_list;
> +
> + dprintf("imsm: allocate_space_list() for update_reshape\n");
> +
> + for (dl = super->devlist; dl; dl = dl->next) {
> + int size = sizeof_imsm_dev(dl->dev, 1);
> + void *s;
> + if (u->new_raid_disks > u->old_raid_disks)
> + size += sizeof(__u32)*2*
> + (u->new_raid_disks - u->old_raid_disks);
> + s = malloc(size);
> + if (!s)
> + return 1;
> + *space_tail = s;
> + space_tail = s;
> + *space_tail = NULL;
> + }
> + return 0;
> +}
> +
> +// static int reallocate_anchor_for_update(struct intel_super *super, struct imsm_update_reshape *u);
> +/*
> + * Check if there is enouht spare and reallocate anchor if neccessary
> + * Return:
> + * 1 - no enouth space for new request
> + * 0 - anchor ready for updates
> + */
> +static int reallocate_anchor_for_update(struct intel_super *super, struct imsm_update_reshape *u)
> +{
> + /* reallocate anchor
> + */
> + size_t buf_len = super->len;
> + size_t len = disks_to_mpb_size(u->new_raid_disks);
> + struct imsm_super *mpb = super->anchor;
> + void *new_anchor;
> +
> + dprintf("imsm: realocate anchore\n");
> +
> + if (__le32_to_cpu(mpb->mpb_size) + len > buf_len) {
> + buf_len = ROUND_UP(__le32_to_cpu(mpb->mpb_size) + len, 512);
> + if (posix_memalign(&new_anchor,
> + 512, buf_len) == 0) {
> + memcpy(new_anchor, super->buf, super->len);
> + free(super->buf);
> + super->buf = new_anchor;
> + super->len = buf_len;
> + } else
> + return 1;
> +
> + }
> + return 0;
> +}
> +
> +/*
> + * Reshape IMSM metadata - prepare metadata update
> + * 0 - update successfully reshaped
> + * 1 - reshape start failed - abort the process
> + */
> static int imsm_reshape_super(struct supertype *st, long long size, int level,
> int layout, int chunksize, int raid_disks,
> char *backup, char *dev, int verbose)
> @@ -6643,6 +6730,9 @@ static int imsm_reshape_super(struct supertype *st, long long size, int level,
>
> dprintf("\tfor level : %i\n", geo.level);
> dprintf("\tfor raid_disks : %i\n", geo.raid_disks);
> + dprintf("\tfor layout : %i\n", geo.layout);
> + dprintf("\tfor size : %llu\n", geo.size);
> + dprintf("\tfor chunksize : %i\n", geo.chunksize);
>
> if (experimental() == 0)
> return ret_val;
> @@ -6734,8 +6824,57 @@ static int imsm_reshape_super(struct supertype *st, long long size, int level,
> } else
> fprintf(stderr, Name "imsm: Operation is not allowed "
> "on this container\n");
> - } else
> - fprintf(stderr, Name "imsm: not a container operation\n");
> + } else {
> + struct imsm_update_reshape *u = NULL;
> + int len;
> + struct intel_super *super = st->sb;
> + void **space_list=NULL;
> +
> + int old_raid_disks = 0;
> +
> + dprintf("imsm: subarray reshape\n");
> + if (imsm_reshape_is_allowed_on_subarray(st, &geo, &old_raid_disks) == 0) {
> + dprintf("imsm: reshape not allowed\n");
> + goto exit_imsm_reshape_super;
> + }
> +
> + len = imsm_create_metadata_update_for_reshape(st, &geo, old_raid_disks, &u);
> +
> + if (len <= 0) {
> + dprintf("imsm: Cannot prepare update\n");
> + goto exit_imsm_reshape_super;
> + }
> +
> + if (mdmon_running(st->container_dev)) {
> + ret_val = 0;
> + append_metadata_update(st, u, len);
> + goto exit_imsm_reshape_super;
> + }
> + /* no mdmon - apply update
> + */
> +
> + dprintf("imsm:prepare space list for update_reshape\n");
> + ret_val = allocate_space_list(super, u, &space_list);
> + if (ret_val == 0) {
> + ret_val = apply_reshape_container_disks_update(u, super, &space_list);
> + /* processed if reshape applied */
> + if (ret_val == 1) {
> + ret_val = reallocate_anchor_for_update(super, u);
> + if (ret_val == 0)
> + super->updates_pending++;
> + }
> + else
> + /* set error code */
> + ret_val = 1;
> + }
> + /* release memory */
> + while (space_list) {
> + void *space = space_list;
> + space_list = *space_list;
> + free(space);
> + }
> + free(u);
> + }
>
> exit_imsm_reshape_super:
> dprintf("imsm: reshape_super Exit code = %i\n", ret_val);
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2011-01-12 6:20 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-01-11 15:24 Subject: [PATCH 4/4] imsm: support for raid0 <-> raid5 migration Labun, Marcin
2011-01-12 6:20 ` NeilBrown
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).