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;
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 ||
if (avail[i])
cnt++;
}
+ /* Also need to reject any spare device with an event count that
+ * is too high
+ */
+ for (d = sra->devs; d; d = d->next) {
+ if (!(d->disk.state & (1<<MD_DISK_SYNC)) &&
+ d->events > max_events)
+ d->disk.state |= (1 << MD_DISK_REMOVED);
+ }
free(best);
free(devmap);
return cnt + replcnt;