]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
imsm: Moves metadata update code for spare activation to separate function
authorLukasz Orlowski <lukasz.orlowski@intel.com>
Sat, 22 Oct 2011 00:38:56 +0000 (11:38 +1100)
committerNeilBrown <neilb@suse.de>
Sat, 22 Oct 2011 00:38:56 +0000 (11:38 +1100)
The metadata update code during spare activation is moved to a separate
function for clarity of code, as a prework for the next patch fixing
the bug.

Signed-off-by: Lukasz Orlowski <lukasz.orlowski@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
super-intel.c

index dfa85aa1b7f6f08f953892cb6d67ecc127303b0c..c8765a4673b8f783f36915a79fd744a44cb36c55 100644 (file)
@@ -6982,6 +6982,108 @@ error_disk_add:
        return ret_val;
 }
 
+static int apply_update_activate_spare(struct imsm_update_activate_spare *u,
+                                      struct intel_super *super,       
+                                      struct active_array *active_array)
+{
+       struct imsm_super *mpb = super->anchor;
+       struct imsm_dev *dev = get_imsm_dev(super, u->array);
+       struct imsm_map *map = get_imsm_map(dev, 0);
+       struct imsm_map *migr_map;
+       struct active_array *a;
+       struct imsm_disk *disk;
+       __u8 to_state;
+       struct dl *dl;
+       unsigned int found;
+       int failed;
+       int victim = get_imsm_disk_idx(dev, u->slot, -1);
+       int i;
+
+       for (dl = super->disks; dl; dl = dl->next)
+               if (dl == u->dl)
+                       break;
+
+       if (!dl) {
+               fprintf(stderr, "error: imsm_activate_spare passed "
+                       "an unknown disk (index: %d)\n",
+                       u->dl->index);
+               return 0;
+       }
+
+       /* count failures (excluding rebuilds and the victim)
+        * to determine map[0] state
+        */
+       failed = 0;
+       for (i = 0; i < map->num_members; i++) {
+               if (i == u->slot)
+                       continue;
+               disk = get_imsm_disk(super,
+                                    get_imsm_disk_idx(dev, i, -1));
+               if (!disk || is_failed(disk))
+                       failed++;
+       }
+
+       /* adding a pristine spare, assign a new index */
+       if (dl->index < 0) {
+               dl->index = super->anchor->num_disks;
+               super->anchor->num_disks++;
+       }
+       disk = &dl->disk;
+       disk->status |= CONFIGURED_DISK;
+       disk->status &= ~SPARE_DISK;
+
+       /* mark rebuild */
+       to_state = imsm_check_degraded(super, dev, failed);
+       map->map_state = IMSM_T_STATE_DEGRADED;
+       migrate(dev, super, to_state, MIGR_REBUILD);
+       migr_map = get_imsm_map(dev, 1);
+       set_imsm_ord_tbl_ent(map, u->slot, dl->index);
+       set_imsm_ord_tbl_ent(migr_map, u->slot,
+                            dl->index | IMSM_ORD_REBUILD);
+
+       /* update the family_num to mark a new container
+        * generation, being careful to record the existing
+        * family_num in orig_family_num to clean up after
+        * earlier mdadm versions that neglected to set it.
+        */
+       if (mpb->orig_family_num == 0)
+               mpb->orig_family_num = mpb->family_num;
+       mpb->family_num += super->random;
+
+       /* count arrays using the victim in the metadata */
+       found = 0;
+       for (a = active_array; a ; a = a->next) {
+               dev = get_imsm_dev(super, a->info.container_member);
+               map = get_imsm_map(dev, 0);
+
+               if (get_imsm_disk_slot(map, victim) >= 0)
+                       found++;
+       }
+
+       /* delete the victim if it is no longer being
+        * utilized anywhere
+        */
+       if (!found) {
+               struct dl **dlp;
+
+               /* We know that 'manager' isn't touching anything,
+                * so it is safe to delete
+                */
+               for (dlp = &super->disks; *dlp; dlp = &(*dlp)->next)
+                       if ((*dlp)->index == victim)
+                               break;
+
+               /* victim may be on the missing list */
+               if (!*dlp)
+                       for (dlp = &super->missing; *dlp;
+                            dlp = &(*dlp)->next)
+                               if ((*dlp)->index == victim)
+                                       break;
+               imsm_delete(super, dlp, victim);
+       }
+
+       return 1;
+}
 
 static int apply_reshape_container_disks_update(struct imsm_update_reshape *u,
                                                struct intel_super *super,
@@ -7276,99 +7378,8 @@ static void imsm_process_update(struct supertype *st,
        }
        case update_activate_spare: {
                struct imsm_update_activate_spare *u = (void *) update->buf; 
-               struct imsm_dev *dev = get_imsm_dev(super, u->array);
-               struct imsm_map *map = get_imsm_map(dev, 0);
-               struct imsm_map *migr_map;
-               struct active_array *a;
-               struct imsm_disk *disk;
-               __u8 to_state;
-               struct dl *dl;
-               unsigned int found;
-               int failed;
-               int victim = get_imsm_disk_idx(dev, u->slot, -1);
-               int i;
-
-               for (dl = super->disks; dl; dl = dl->next)
-                       if (dl == u->dl)
-                               break;
-
-               if (!dl) {
-                       fprintf(stderr, "error: imsm_activate_spare passed "
-                               "an unknown disk (index: %d)\n",
-                               u->dl->index);
-                       return;
-               }
-
-               super->updates_pending++;
-               /* count failures (excluding rebuilds and the victim)
-                * to determine map[0] state
-                */
-               failed = 0;
-               for (i = 0; i < map->num_members; i++) {
-                       if (i == u->slot)
-                               continue;
-                       disk = get_imsm_disk(super,
-                                            get_imsm_disk_idx(dev, i, -1));
-                       if (!disk || is_failed(disk))
-                               failed++;
-               }
-
-               /* adding a pristine spare, assign a new index */
-               if (dl->index < 0) {
-                       dl->index = super->anchor->num_disks;
-                       super->anchor->num_disks++;
-               }
-               disk = &dl->disk;
-               disk->status |= CONFIGURED_DISK;
-               disk->status &= ~SPARE_DISK;
-
-               /* mark rebuild */
-               to_state = imsm_check_degraded(super, dev, failed);
-               map->map_state = IMSM_T_STATE_DEGRADED;
-               migrate(dev, super, to_state, MIGR_REBUILD);
-               migr_map = get_imsm_map(dev, 1);
-               set_imsm_ord_tbl_ent(map, u->slot, dl->index);
-               set_imsm_ord_tbl_ent(migr_map, u->slot, dl->index | IMSM_ORD_REBUILD);
-
-               /* update the family_num to mark a new container
-                * generation, being careful to record the existing
-                * family_num in orig_family_num to clean up after
-                * earlier mdadm versions that neglected to set it.
-                */
-               if (mpb->orig_family_num == 0)
-                       mpb->orig_family_num = mpb->family_num;
-               mpb->family_num += super->random;
-
-               /* count arrays using the victim in the metadata */
-               found = 0;
-               for (a = st->arrays; a ; a = a->next) {
-                       dev = get_imsm_dev(super, a->info.container_member);
-                       map = get_imsm_map(dev, 0);
-
-                       if (get_imsm_disk_slot(map, victim) >= 0)
-                               found++;
-               }
-
-               /* delete the victim if it is no longer being
-                * utilized anywhere
-                */
-               if (!found) {
-                       struct dl **dlp;
-
-                       /* We know that 'manager' isn't touching anything,
-                        * so it is safe to delete
-                        */
-                       for (dlp = &super->disks; *dlp; dlp = &(*dlp)->next)
-                               if ((*dlp)->index == victim)
-                                       break;
-
-                       /* victim may be on the missing list */
-                       if (!*dlp)
-                               for (dlp = &super->missing; *dlp; dlp = &(*dlp)->next)
-                                       if ((*dlp)->index == victim)
-                                               break;
-                       imsm_delete(super, dlp, victim);
-               }
+               if (apply_update_activate_spare(u, super, st->arrays))
+                       super->updates_pending++;
                break;
        }
        case update_create_array: {