]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Assemble.c
Remove lots of unnecessary white space.
[thirdparty/mdadm.git] / Assemble.c
index b45abc2f408d4ad27ff4f7d55a03af8b51470d62..8e3c929f4440158b63a486112c17fa473219fb9f 100644 (file)
@@ -690,11 +690,12 @@ static int load_devices(struct devs *devices, char *devmap,
                devices[devcnt].i = *content;
                devices[devcnt].i.disk.major = major(stb.st_rdev);
                devices[devcnt].i.disk.minor = minor(stb.st_rdev);
-               if (most_recent < devcnt) {
-                       if (devices[devcnt].i.events
-                           > devices[most_recent].i.events)
+
+               if (devices[devcnt].i.events
+                   > devices[most_recent].i.events &&
+                   devices[devcnt].i.disk.state == 6)
                                most_recent = devcnt;
-               }
+
                if (content->array.level == LEVEL_MULTIPATH)
                        /* with multipath, the raid_disk from the superblock is meaningless */
                        i = devcnt;
@@ -882,7 +883,8 @@ static int start_array(int mdfd,
                       unsigned int rebuilding_cnt,
                       struct context *c,
                       int clean, char *avail,
-                      int start_partial_ok
+                      int start_partial_ok,
+                      int was_forced
        )
 {
        int rv;
@@ -1063,6 +1065,17 @@ static int start_array(int mdfd,
                                        }
                                }
                        }
+                       printf("l=%d o=%d r=%d w=%d\n",content->array.level,
+                              okcnt, content->array.raid_disks, was_forced);
+                       if (content->array.level == 6 &&
+                           okcnt + 1 == (unsigned)content->array.raid_disks &&
+                           was_forced) {
+                               struct mdinfo *sra = sysfs_read(mdfd, NULL, 0);
+                               if (sra)
+                                       sysfs_set_str(sra, NULL,
+                                                     "sync_action", "repair");
+                               sysfs_free(sra);
+                       }
                        return 0;
                }
                pr_err("failed to RUN_ARRAY %s: %s\n",
@@ -1189,6 +1202,7 @@ int Assemble(struct supertype *st, char *mddev,
        int devcnt;
        unsigned int okcnt, sparecnt, rebuilding_cnt, replcnt;
        int i;
+       int was_forced = 0;
        int most_recent = 0;
        int chosen_drive;
        int change = 0;
@@ -1248,7 +1262,7 @@ try_again:
                                  inargv, auto_assem);
        if (num_devs < 0)
                return 1;
-       
+
        if (!st || !st->sb || !content)
                return 2;
 
@@ -1456,8 +1470,15 @@ try_again:
                        best[i] = -1;
                        continue;
                }
+               /* Require event counter to be same as, or just less than,
+                * most recent.  If it is bigger, it must be a stray spare and
+                * should be ignored.
+                */
                if (devices[j].i.events+event_margin >=
-                   devices[most_recent].i.events) {
+                   devices[most_recent].i.events &&
+                   devices[j].i.events <=
+                   devices[most_recent].i.events
+                       ) {
                        devices[j].uptodate = 1;
                        if (i < content->array.raid_disks * 2) {
                                if (devices[j].i.recovery_start == MaxSector ||
@@ -1477,10 +1498,13 @@ try_again:
                }
        }
        free(devmap);
-       if (c->force)
-               okcnt += force_array(content, devices, best, bestcnt,
-                                    avail, most_recent, st, c);
-
+       if (c->force) {
+               int force_ok = force_array(content, devices, best, bestcnt,
+                                          avail, most_recent, st, c);
+               okcnt += force_ok;
+               if (force_ok)
+                       was_forced = 1;
+       }
        /* Now we want to look at the superblock which the kernel will base things on
         * and compare the devices that we think are working with the devices that the
         * superblock thinks are working.
@@ -1576,6 +1600,7 @@ try_again:
                change += st->ss->update_super(st, content, "force-array",
                                               devices[chosen_drive].devname, c->verbose,
                                               0, NULL);
+               was_forced = 1;
                clean = 1;
        }
 
@@ -1681,7 +1706,7 @@ try_again:
                         chosen_drive, devices, okcnt, sparecnt,
                         rebuilding_cnt,
                         c,
-                        clean, avail, start_partial_ok);
+                        clean, avail, start_partial_ok, was_forced);
        if (rv == 1 && !pre_exist)
                ioctl(mdfd, STOP_ARRAY, NULL);
        free(devices);
@@ -1872,4 +1897,3 @@ int assemble_container_content(struct supertype *st, int mdfd,
        }
 }
 #endif
-