diff options
author | Krzysztof Wojcik <krzysztof.wojcik@intel.com> | 2011-01-17 12:52:36 +1100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2011-01-17 12:52:36 +1100 |
commit | 471bceb68151d322a97810a52f07512beadf4bd7 (patch) | |
tree | bf1c68eaf58e28073f1c4a44bce2c0aae330d85c /super-intel.c | |
parent | 300f503323bc601ec7f5e30cc798c3a711c6d373 (diff) |
Define imsm_analyze_change function
Function intended to use for single volume migration.
Function analyze transition and validate if it is supported.
Signed-off-by: Krzysztof Wojcik <krzysztof.wojcik@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'super-intel.c')
-rw-r--r-- | super-intel.c | 146 |
1 files changed, 131 insertions, 15 deletions
diff --git a/super-intel.c b/super-intel.c index cb2b51b6..d86e8d81 100644 --- a/super-intel.c +++ b/super-intel.c @@ -6547,16 +6547,113 @@ static void imsm_update_metadata_locally(struct supertype *st, } } -/******************************************************************************* +/*************************************************************************** * Function: imsm_analyze_change -* Description: Function analyze and validate change for single volume migration +* Description: Function analyze change for single volume +* and validate if transition is supported * Parameters: Geometry parameters, supertype structure * Returns: Operation type code on success, -1 if fail -********************************************************************************/ -enum imsm_reshape_type imsm_analyze_change( - struct supertype *st, struct geo_params *geo) +****************************************************************************/ +enum imsm_reshape_type imsm_analyze_change(struct supertype *st, + struct geo_params *geo) { - return -1; + struct mdinfo info; + int change = -1; + int check_devs = 0; + + getinfo_super_imsm_volume(st, &info, NULL); + + if ((geo->level != info.array.level) && + (geo->level >= 0) && + (geo->level != UnSet)) { + switch (info.array.level) { + case 0: + if (geo->level == 5) { + change = CH_LEVEL_MIGRATION; + check_devs = 1; + } + if (geo->level == 10) { + change = CH_TAKEOVER; + check_devs = 1; + } + break; + case 5: + if (geo->level != 0) + change = CH_LEVEL_MIGRATION; + break; + case 10: + if (geo->level == 0) { + change = CH_TAKEOVER; + check_devs = 1; + } + break; + } + if (change == -1) { + fprintf(stderr, + Name " Error. Level Migration from %d to %d " + "not supported!\n", + info.array.level, geo->level); + goto analyse_change_exit; + } + } else + geo->level = info.array.level; + + if ((geo->layout != info.array.layout) + && ((geo->layout != UnSet) && (geo->layout != -1))) { + change = CH_LEVEL_MIGRATION; + if ((info.array.layout == 0) + && (info.array.level == 5) + && (geo->layout == 5)) { + /* reshape 5 -> 4 */ + } else if ((info.array.layout == 5) + && (info.array.level == 5) + && (geo->layout == 0)) { + /* reshape 4 -> 5 */ + geo->layout = 0; + geo->level = 5; + } else { + fprintf(stderr, + Name " Error. Layout Migration from %d to %d " + "not supported!\n", + info.array.layout, geo->layout); + change = -1; + goto analyse_change_exit; + } + } else + geo->layout = info.array.layout; + + if ((geo->chunksize > 0) && (geo->chunksize != UnSet) + && (geo->chunksize != info.array.chunk_size)) + change = CH_CHUNK_MIGR; + else + geo->chunksize = info.array.chunk_size; + + if (!validate_geometry_imsm(st, + geo->level, + geo->layout, + geo->raid_disks, + (geo->chunksize / 1024), + geo->size, + 0, 0, 1)) + change = -1; + + if (check_devs) { + struct intel_super *super = st->sb; + struct imsm_super *mpb = super->anchor; + + if (mpb->num_raid_devs > 1) { + fprintf(stderr, + Name " Error. Cannot perform operation on %s" + "- for this operation it MUST be single " + "array in container\n", + geo->dev_name); + change = -1; + } + } + +analyse_change_exit: + + return change; } static int imsm_reshape_super(struct supertype *st, long long size, int level, @@ -6616,22 +6713,41 @@ static int imsm_reshape_super(struct supertype *st, long long size, int level, } } else { /* On volume level we support following operations - * - takeover: raid10 -> raid0; raid0 -> raid10 - * - chunk size migration - * - migration: raid5 -> raid0; raid0 -> raid5 - */ - int change; + * - takeover: raid10 -> raid0; raid0 -> raid10 + * - chunk size migration + * - migration: raid5 -> raid0; raid0 -> raid5 + */ + struct intel_super *super = st->sb; + struct intel_dev *dev = super->devlist; + int change, devnum; dprintf("imsm: info: Volume operation\n"); + /* find requested device */ + while (dev) { + imsm_find_array_minor_by_subdev(dev->index, st->container_dev, &devnum); + if (devnum == geo.dev_id) + break; + dev = dev->next; + } + if (dev == NULL) { + fprintf(stderr, Name " Cannot find %s (%i) subarray\n", + geo.dev_name, geo.dev_id); + goto exit_imsm_reshape_super; + } + super->current_vol = dev->index; change = imsm_analyze_change(st, &geo); switch (change) { - case CH_TAKEOVER: + case CH_TAKEOVER: + ret_val = 0; break; - case CH_CHUNK_MIGR: + case CH_CHUNK_MIGR: + ret_val = 0; break; - case CH_LEVEL_MIGRATION: + case CH_LEVEL_MIGRATION: + ret_val = 0; break; + default: + ret_val = 1; } - ret_val = 0; } exit_imsm_reshape_super: |