]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Avoid skipping devices where removing all faulty/detached devices.
authorNeilBrown <neilb@suse.de>
Wed, 30 Jun 2010 07:20:38 +0000 (17:20 +1000)
committerNeilBrown <neilb@suse.de>
Wed, 30 Jun 2010 07:20:38 +0000 (17:20 +1000)
When using 0.90 metadata, devices can be renumbered when
earlier devices are removed.
So when iterating all devices looking for 'failed' or 'detached'
devices, we need to re-check the same slot we checked last time
to see if maybe it has a different device now.

Reported-by: Jim Paris <jim@jtan.com>
Resolves-Debian-Bug: 587550
Signed-off-by: NeilBrown <neilb@suse.de>
Manage.c

index 6bc5d0ae9476c5eb3f273fcb621753454eee67a6..edf41e9cf06914c459798a518de1d1ac6a434f12 100644 (file)
--- a/Manage.c
+++ b/Manage.c
@@ -376,6 +376,7 @@ int Manage_subdevs(char *devname, int fd,
                return 1;
        }
 
+       stb.st_rdev = 0;
        for (dv = devlist, j=0 ; dv; dv = next, j = jnext) {
                unsigned long long ldsize;
                char dvname[20];
@@ -394,6 +395,7 @@ int Manage_subdevs(char *devname, int fd,
                                return 1;
                        }
                        for (; j < array.raid_disks + array.nr_disks ; j++) {
+                               int dev;
                                disc.number = j;
                                if (ioctl(fd, GET_DISK_INFO, &disc))
                                        continue;
@@ -401,9 +403,15 @@ int Manage_subdevs(char *devname, int fd,
                                        continue;
                                if ((disc.state & 1) == 0) /* faulty */
                                        continue;
-                               stb.st_rdev = makedev(disc.major, disc.minor);
+                               dev = makedev(disc.major, disc.minor);
+                               if (stb.st_rdev == dev)
+                                       /* already did that one */
+                                       continue;
+                               stb.st_rdev = dev;
                                next = dv;
-                               jnext = j+1;
+                               /* same slot again next time - things might
+                                * have reshuffled */
+                               jnext = j;
                                sprintf(dvname,"%d:%d", disc.major, disc.minor);
                                dnprintable = dvname;
                                break;
@@ -419,6 +427,7 @@ int Manage_subdevs(char *devname, int fd,
                        }
                        for (; j < array.raid_disks + array.nr_disks; j++) {
                                int sfd;
+                               int dev;
                                disc.number = j;
                                if (ioctl(fd, GET_DISK_INFO, &disc))
                                        continue;
@@ -435,9 +444,15 @@ int Manage_subdevs(char *devname, int fd,
                                        continue;
                                if (errno != ENXIO)
                                        continue;
-                               stb.st_rdev = makedev(disc.major, disc.minor);
+                               dev = makedev(disc.major, disc.minor);
+                               if (stb.st_rdev == dev)
+                                       /* already did that one */
+                                       continue;
+                               stb.st_rdev = dev;
                                next = dv;
-                               jnext = j+1;
+                               /* same slot again next time - things might
+                                * have reshuffled */
+                               jnext = j;
                                dnprintable = dvname;
                                break;
                        }