summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2010-06-30 17:20:38 +1000
committerNeilBrown <neilb@suse.de>2010-06-30 17:20:38 +1000
commitb3b4e8a7a229cccca915421329a5319f996b0842 (patch)
tree4ce51feb3e658720b78750f4da215cb5d84e3d95
parent7efa6bc34ff0357a491e64495a9b3a7483971000 (diff)
downloadmdadm-b3b4e8a7a229cccca915421329a5319f996b0842.tar.gz
mdadm-b3b4e8a7a229cccca915421329a5319f996b0842.tar.xz
mdadm-b3b4e8a7a229cccca915421329a5319f996b0842.zip
Avoid skipping devices where removing all faulty/detached devices.
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>
-rw-r--r--Manage.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/Manage.c b/Manage.c
index 6bc5d0a..edf41e9 100644
--- 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;
}