diff --git a/Create.c b/Create.c index 8a73799..c96b319 100644 --- a/Create.c +++ b/Create.c @@ -792,7 +792,39 @@ int Create(struct supertype *st, char *mddev, dv == moved_disk && dnum != insert_point) break; } if (pass == 1) { + struct mdinfo info_new; + struct map_ent *me = NULL; + + /* check to see if the uuid has changed due to these + * metadata changes, and if so update the member array + * and container uuid. Note ->write_init_super clears + * the subarray cursor such that ->getinfo_super once + * again returns container info. + */ + map_lock(&map); + st->ss->getinfo_super(st, &info_new); + if (st->ss->external && level != LEVEL_CONTAINER && + !same_uuid(info_new.uuid, info.uuid, 0)) { + map_update(&map, fd2devnum(mdfd), + info_new.text_version, + info_new.uuid, chosen_name); + me = map_by_devnum(&map, st->container_dev); + } + st->ss->write_init_super(st); + + /* update parent container uuid */ + if (me) { + char *path = strdup(me->path); + + st->ss->getinfo_super(st, &info_new); + map_update(&map, st->container_dev, + info_new.text_version, + info_new.uuid, path); + free(path); + } + map_unlock(&map); + flush_metadata_updates(st); } } diff --git a/super-ddf.c b/super-ddf.c index 8153924..0b15275 100644 --- a/super-ddf.c +++ b/super-ddf.c @@ -2362,15 +2362,19 @@ static int __write_init_super_ddf(struct supertype *st, int do_close) static int write_init_super_ddf(struct supertype *st) { + struct ddf_super *ddf = st->sb; + struct vcl *currentconf = ddf->currentconf; + + /* we are done with currentconf reset it to point st at the container */ + ddf->currentconf = NULL; if (st->update_tail) { /* queue the virtual_disk and vd_config as metadata updates */ struct virtual_disk *vd; struct vd_config *vc; - struct ddf_super *ddf = st->sb; int len; - if (!ddf->currentconf) { + if (!currentconf) { int len = (sizeof(struct phys_disk) + sizeof(struct phys_disk_entry)); @@ -2389,14 +2393,14 @@ static int write_init_super_ddf(struct supertype *st) len = sizeof(struct virtual_disk) + sizeof(struct virtual_entry); vd = malloc(len); *vd = *ddf->virt; - vd->entries[0] = ddf->virt->entries[ddf->currentconf->vcnum]; - vd->populated_vdes = __cpu_to_be16(ddf->currentconf->vcnum); + vd->entries[0] = ddf->virt->entries[currentconf->vcnum]; + vd->populated_vdes = __cpu_to_be16(currentconf->vcnum); append_metadata_update(st, vd, len); /* Then the vd_config */ len = ddf->conf_rec_len * 512; vc = malloc(len); - memcpy(vc, &ddf->currentconf->conf, len); + memcpy(vc, ¤tconf->conf, len); append_metadata_update(st, vc, len); /* FIXME I need to close the fds! */ diff --git a/super-intel.c b/super-intel.c index 207d3be..56947de 100644 --- a/super-intel.c +++ b/super-intel.c @@ -2724,17 +2724,16 @@ static int write_super_imsm(struct intel_super *super, int doclose) } -static int create_array(struct supertype *st) +static int create_array(struct supertype *st, int dev_idx) { size_t len; struct imsm_update_create_array *u; struct intel_super *super = st->sb; - struct imsm_dev *dev = get_imsm_dev(super, super->current_vol); + struct imsm_dev *dev = get_imsm_dev(super, dev_idx); struct imsm_map *map = get_imsm_map(dev, 0); struct disk_info *inf; struct imsm_disk *disk; int i; - int idx; len = sizeof(*u) - sizeof(*dev) + sizeof_imsm_dev(dev, 0) + sizeof(*inf) * map->num_members; @@ -2746,11 +2745,12 @@ static int create_array(struct supertype *st) } u->type = update_create_array; - u->dev_idx = super->current_vol; + u->dev_idx = dev_idx; imsm_copy_dev(&u->dev, dev); inf = get_disk_info(u); for (i = 0; i < map->num_members; i++) { - idx = get_imsm_disk_idx(dev, i); + int idx = get_imsm_disk_idx(dev, i); + disk = get_imsm_disk(super, idx); serialcpy(inf[i].serial, disk->serial); } @@ -2784,21 +2784,26 @@ static int _add_disk(struct supertype *st) static int write_init_super_imsm(struct supertype *st) { + struct intel_super *super = st->sb; + int current_vol = super->current_vol; + + /* we are done with current_vol reset it to point st at the container */ + super->current_vol = -1; + if (st->update_tail) { /* queue the recently created array / added disk * as a metadata update */ - struct intel_super *super = st->sb; struct dl *d; int rv; /* determine if we are creating a volume or adding a disk */ - if (super->current_vol < 0) { + if (current_vol < 0) { /* in the add disk case we are running in mdmon * context, so don't close fd's */ return _add_disk(st); } else - rv = create_array(st); + rv = create_array(st, current_vol); for (d = super->disks; d ; d = d->next) { close(d->fd);