]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
imsm: FIX: Perform first metadata update for container operation
authorAdam Kwolek <adam.kwolek@intel.com>
Thu, 6 Jan 2011 05:24:07 +0000 (16:24 +1100)
committerNeilBrown <neilb@suse.de>
Thu, 6 Jan 2011 05:24:07 +0000 (16:24 +1100)
Meta data was not updated due to the following problems:
1.disk index < 0 was treated as invalid, but this is spare device
2. disk index greater than currently used disks is correct also
3. newmap pointer has to be refreshed for second map copy operation
4. size calculation has to be guarded for shrinking operation

Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
super-intel.c

index 122ce5fe08077eaddd4fb262f609f9cc49a027f6..5e23078c4e6998ab3109929985f3109a03c89028 100644 (file)
@@ -5602,7 +5602,13 @@ static void imsm_process_update(struct supertype *st,
                        new_disk = get_disk_super(super,
                                                  major(u->new_disks[i]),
                                                  minor(u->new_disks[i]));
-                       if (new_disk == NULL || new_disk->index < 0)
+                       dprintf("imsm: imsm_process_update(): new disk "\
+                               "for reshape is: %i:%i (%p, index = %i)\n",
+                               major(u->new_disks[i]), minor(u->new_disks[i]),
+                               new_disk, new_disk->index);
+                       if ((new_disk == NULL) ||
+                           ((new_disk->index >= 0) &&
+                            (new_disk->index < u->old_raid_disks)))
                                goto update_reshape_exit;
 
                        new_disk->index = mpb->num_disks++;
@@ -5642,7 +5648,7 @@ static void imsm_process_update(struct supertype *st,
                                                     u->old_raid_disks + i);
                        }
                        /* New map is correct, now need to save old map */
-                       oldmap = get_imsm_map(newdev, 1);
+                       newmap = get_imsm_map(newdev, 1);
                        memcpy(newmap, oldmap, sizeof_imsm_map(oldmap));
 
                        sp = (void **)id->dev;
@@ -5987,8 +5993,9 @@ static void imsm_prepare_update(struct supertype *st,
                for (dl = super->devlist; dl; dl = dl->next) {
                        int size = sizeof_imsm_dev(dl->dev, 1);
                        void *s;
-                       size += sizeof(__u32) * 2 * 
-                               (u->new_raid_disks - u->old_raid_disks);
+                       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;
@@ -6361,11 +6368,14 @@ abort:
         */
        sysfs_free(spares);
 
+       dprintf("imsm: reshape update preparation :");
        if (i == delta_disks) {
+               dprintf(" OK\n");
                *updatep = u;
                return update_memory_size;
        }
        free(u);
+       dprintf(" Error\n");
 
        return 0;
 }