summaryrefslogtreecommitdiff
path: root/Assemble.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2013-09-02 11:48:06 +1000
committerNeilBrown <neilb@suse.de>2013-09-02 11:48:06 +1000
commita792ece6768143ea557c63e35437536b9d235bb4 (patch)
tree2f74d163cd3d8ba12a74e7508e15e3c1487427ef /Assemble.c
parent2f1bcf43d93a991845b2ebee76850bd4dc5bc7fc (diff)
Assemble: don't ever consider a 'spare' to be the 'most recent'.
If all devices have the same event count and the first one is a spare, then that spare will be the 'most_recent'. However then other devices will think the 'most_recent' has failed (for v0.90 metadata) and will be rejected from the array. So never consider a 'spare' to be 'most recent'. Reported-by: Andreas Baer <synthetic.gods@gmail.com> Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Assemble.c')
-rw-r--r--Assemble.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/Assemble.c b/Assemble.c
index 32e05b03..60a52b2b 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -564,7 +564,7 @@ static int load_devices(struct devs *devices, char *devmap,
#ifndef MDASSEMBLE
int bitmap_done = 0;
#endif
- int most_recent = 0;
+ int most_recent = -1;
int bestcnt = 0;
int *best = *bestp;
@@ -695,10 +695,12 @@ static int load_devices(struct devs *devices, char *devmap,
devices[devcnt].i.disk.major = major(stb.st_rdev);
devices[devcnt].i.disk.minor = minor(stb.st_rdev);
- if (devices[devcnt].i.events
- > devices[most_recent].i.events &&
- devices[devcnt].i.disk.state == 6)
+ if (devices[devcnt].i.disk.state == 6) {
+ if (most_recent < 0 ||
+ devices[devcnt].i.events
+ > devices[most_recent].i.events)
most_recent = devcnt;
+ }
if (content->array.level == LEVEL_MULTIPATH)
/* with multipath, the raid_disk from the superblock is meaningless */
@@ -766,7 +768,8 @@ static int load_devices(struct devs *devices, char *devmap,
}
devcnt++;
}
- *most_recentp = most_recent;
+ if (most_recent >= 0)
+ *most_recentp = most_recent;
*bestcntp = bestcnt;
*bestp = best;
return devcnt;