summaryrefslogtreecommitdiff
path: root/Assemble.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2013-06-17 16:55:31 +1000
committerNeilBrown <neilb@suse.de>2013-06-17 16:55:31 +1000
commitf80057aec5d314798251e318555cb8ac92e4c06f (patch)
treea608c1049fce2ca0719c46847ea00afa4b44f7dc /Assemble.c
parente2f408a4c03115452fdf467b75a8e1e5eee8cb6e (diff)
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>
Diffstat (limited to 'Assemble.c')
-rw-r--r--Assemble.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/Assemble.c b/Assemble.c
index b45abc2f..c927c209 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -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 ||