Assemble/Incr: Don't include spares with too-high event count.

Some failure scenarios can leave a spare with a higher event count
than an in-sync device.  Assembling an array like this will confuse
the kernel.
So detect spares with event counts higher than the best non-spare
event count and exclude them from the array.

Reported-by: Alexander Lyakas <alex.bolshoy@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
NeilBrown 2013-06-17 16:55:31 +10:00
parent e2f408a4c0
commit f80057aec5
2 changed files with 21 additions and 5 deletions

View 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;
@ -1456,8 +1457,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 ||

View File

@ -760,6 +760,14 @@ static int count_active(struct supertype *st, struct mdinfo *sra,
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;