summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Create.c32
-rw-r--r--super-ddf.c14
-rw-r--r--super-intel.c21
3 files changed, 54 insertions, 13 deletions
diff --git a/Create.c b/Create.c
index 8a73799c..c96b3195 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 8153924e..0b152759 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, &currentconf->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 207d3be9..56947ded 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);