When raid0 reshape is performed metadata has to be applied by mdadm. (without mdmon) Signed-off-by: Adam Kwolek <adam.kwolek@xxxxxxxxx> --- super-intel.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 71 insertions(+), 11 deletions(-) diff --git a/super-intel.c b/super-intel.c index 565afd4..1be0e72 100644 --- a/super-intel.c +++ b/super-intel.c @@ -6595,36 +6595,96 @@ static int imsm_reshape_super(struct supertype *st, long long size, int level, return ret_val; /* verify reshape conditions - * on container level we can only increase number of devices. */ + * on container level we can only increase number of devices. + */ if (st->container_dev == st->devnum) { /* check for delta_disks > 0 - *and supported raid levels 0 and 5 only in container */ + * and supported raid levels 0 and 5 only in container + */ int old_raid_disks = 0; if (imsm_reshape_is_allowed_on_container( st, &geo, &old_raid_disks)) { struct imsm_update_reshape *u = NULL; int len; + struct intel_super *super = st->sb; + void **space_list; + struct intel_dev *dl; + void **space_tail = (void **)&space_list; + len = imsm_create_metadata_update_for_reshape( st, &geo, old_raid_disks, &u); - if (len) { + if (len <= 0) { + dprintf("imsm: Cannot prepare update\n"); + goto exit_imsm_reshape_super; + + } + if (mdmon_running(st->container_dev)) { ret_val = 0; - if (mdmon_running(st->container_dev)) - append_metadata_update(st, u, len); - else { - /* no mdmon - apply update - */ + append_metadata_update(st, u, len); + goto exit_imsm_reshape_super; + } + + /* no mdmon - apply update + */ + + dprintf("imsm:prepare 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) + break; + *space_tail = s; + space_tail = s; + *space_tail = NULL; + } + ret_val = apply_reshape_container_disks_update(u, super, + &space_list, 1); + if (ret_val) { + /* 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; + + 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; + } + super->updates_pending++; + ret_val = 0; + } + } else { + while (space_list) { + void *space = space_list; + space_list = *space_list; + free(space); } - } else - dprintf("imsm: Cannot prepare "\ - "update\n"); + free(u); + } } else fprintf(stderr, Name "imsm: Operation is not allowed "\ "on this container\n"); } else dprintf("imsm: not a container operation\n"); +exit_imsm_reshape_super: dprintf("imsm: reshape_super Exit code = %i\n", ret_val); return ret_val; } -- To unsubscribe from this list: send the line "unsubscribe linux-raid" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html