]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
imsm: FIX: Support metadata changes rollback
authorAdam Kwolek <adam.kwolek@intel.com>
Fri, 13 Apr 2012 14:52:00 +0000 (16:52 +0200)
committerNeilBrown <neilb@suse.de>
Tue, 17 Apr 2012 02:33:37 +0000 (12:33 +1000)
Add metadata rollback specific code for imsm.
Let reshape_super() ability to differentiate metadata apply and rollback
actions.

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

index 32a53d1da0c590a10d0b07bf511c7cc4a2a612b0..49e383f71c5e26fad1ee20d35b79fc3b5280c428 100644 (file)
@@ -9470,7 +9470,8 @@ static int imsm_find_array_minor_by_subdev(int subdev, int container, int *minor
 
 static int imsm_reshape_is_allowed_on_container(struct supertype *st,
                                                struct geo_params *geo,
-                                               int *old_raid_disks)
+                                               int *old_raid_disks,
+                                               int direction)
 {
        /* currently we only support increasing the number of devices
         * for a container.  This increases the number of device for each
@@ -9494,6 +9495,12 @@ static int imsm_reshape_is_allowed_on_container(struct supertype *st,
                return ret_val;
        }
 
+       if (direction == ROLLBACK_METADATA_CHANGES) {
+               dprintf("imsm: Metadata changes rollback is not supported for "
+                       "container operation.\n");
+               return ret_val;
+       }
+
        info = container_content_imsm(st, NULL);
        for (member = info; member; member = member->next) {
                int result;
@@ -9814,11 +9821,13 @@ static void imsm_update_metadata_locally(struct supertype *st,
 * Function:    imsm_analyze_change
 * Description: Function analyze change for single volume
 *              and validate if transition is supported
-* Parameters:  Geometry parameters, supertype structure
+* Parameters:  Geometry parameters, supertype structure,
+*              metadata change direction (apply/rollback)
 * Returns:     Operation type code on success, -1 if fail
 ****************************************************************************/
 enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
-                                          struct geo_params *geo)
+                                          struct geo_params *geo,
+                                          int direction)
 {
        struct mdinfo info;
        int change = -1;
@@ -9937,18 +9946,24 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
                        goto analyse_change_exit;
                }
                geo->size *= 2;
-               /* round size due to metadata compatibility
-                */
-               geo->size = (geo->size >> SECT_PER_MB_SHIFT)
-                           << SECT_PER_MB_SHIFT;
-               dprintf("Prepare update for size change to %llu\n", geo->size );
-               if (current_size >= geo->size) {
-                       fprintf(stderr,
-                               Name " Error. Size expanssion is supported only"
-                               " (current size is %llu, requested size "
-                               "/rounded/ is %llu).\n",
-                               current_size, geo->size);
-                       goto analyse_change_exit;
+               if ((direction == ROLLBACK_METADATA_CHANGES)) {
+                       /* accept size for rollback only
+                       */
+               } else {
+                       /* round size due to metadata compatibility
+                       */
+                       geo->size = (geo->size >> SECT_PER_MB_SHIFT)
+                                   << SECT_PER_MB_SHIFT;
+                       dprintf("Prepare update for size change to %llu\n",
+                               geo->size );
+                       if (current_size >= geo->size) {
+                               fprintf(stderr,
+                                       Name " Error. Size expanssion is "
+                                       "supported only (current size is %llu, "
+                                       "requested size /rounded/ is %llu).\n",
+                                       current_size, geo->size);
+                               goto analyse_change_exit;
+                       }
                }
                geo->size *= data_disks;
                geo->raid_disks = dev->vol.map->num_members;
@@ -9978,7 +9993,12 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
        }
 
 analyse_change_exit:
-
+       if ((direction == ROLLBACK_METADATA_CHANGES) &&
+            ((change == CH_MIGRATION) || (change == CH_TAKEOVER))) {
+               dprintf("imsm: Metadata changes rollback is not supported for "
+                       "migration and takeover operations.\n");
+               change = -1;
+       }
        return change;
 }
 
@@ -10049,7 +10069,7 @@ static int imsm_reshape_super(struct supertype *st, long long size, int level,
                int old_raid_disks = 0;
 
                if (imsm_reshape_is_allowed_on_container(
-                           st, &geo, &old_raid_disks)) {
+                           st, &geo, &old_raid_disks, direction)) {
                        struct imsm_update_reshape *u = NULL;
                        int len;
 
@@ -10098,7 +10118,7 @@ static int imsm_reshape_super(struct supertype *st, long long size, int level,
                        goto exit_imsm_reshape_super;
                }
                super->current_vol = dev->index;
-               change = imsm_analyze_change(st, &geo);
+               change = imsm_analyze_change(st, &geo, direction);
                switch (change) {
                case CH_TAKEOVER:
                        ret_val = imsm_takeover(st, &geo);