Make Assemble/Force work on raid6 with 2 missing devices.

Previously it onl worked when one missing device.
Also split the "force" update_super method into two and it
is really serving two functions.
This commit is contained in:
Neil Brown 2006-12-14 17:30:51 +11:00
parent 434b77559e
commit 67a8c82d60
5 changed files with 29 additions and 7 deletions

View File

@ -656,7 +656,9 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
continue;
}
info.events = devices[most_recent].events;
st->ss->update_super(&info, super, "force", devices[chosen_drive].devname, verbose, 0, NULL);
st->ss->update_super(&info, super, "force-one",
devices[chosen_drive].devname, verbose,
0, NULL);
if (st->ss->store_super(st, fd, super)) {
close(fd);
@ -752,10 +754,10 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
}
#endif
}
if (force && okcnt == info.array.raid_disks-1) {
/* FIXME check event count */
change += st->ss->update_super(&info, super, "force",
devices[chosen_drive].devname, verbose, 0, NULL);
if (force && okcnt < info.array.raid_disks) {
change += st->ss->update_super(&info, super, "force-array",
devices[chosen_drive].devname, verbose,
0, NULL);
}
if (change) {

View File

@ -2,6 +2,10 @@ Changes Prior to this release
- Fixed UUID printing in "--detail --brief" for version1 metadata.
- --update=resync did exactly the wrong thing for version1 metadata.
It caused a resync to not happen, rather than to happen.
- Allow --assemble --force to mark a raid6 clean when it has two
missing devices (which is needed else if won't assemble.
Without this fix it would only assemble if one or zero
missing devices.
Changes Prior to 2.5.6 release
- Fix bug which meant "bitmap=xxx" in mdadm.conf was not handled

View File

@ -411,13 +411,21 @@ static int update_super0(struct mdinfo *info, void *sbv, char *update,
} else if (i >= sb->raid_disks && sb->disks[i].number == 0)
sb->disks[i].state = 0;
}
if (strcmp(update, "force")==0) {
if (strcmp(update, "force-one")==0) {
/* Not enough devices for a working array, so
* bring this one up-to-date.
*/
__u32 ehi = sb->events_hi, elo = sb->events_lo;
sb->events_hi = (info->events>>32) & 0xFFFFFFFF;
sb->events_lo = (info->events) & 0xFFFFFFFF;
if (sb->events_hi != ehi ||
sb->events_lo != elo)
rv = 1;
}
if (strcmp(update, "force-array")==0) {
/* degraded array and 'force' requested, so
* maybe need to mark it 'clean'
*/
if ((sb->level == 5 || sb->level == 4 || sb->level == 6) &&
(sb->state & (1 << MD_SB_CLEAN)) == 0) {
/* need to force clean */

View File

@ -485,10 +485,18 @@ static int update_super1(struct mdinfo *info, void *sbv, char *update,
int rv = 0;
struct mdp_superblock_1 *sb = sbv;
if (strcmp(update, "force")==0) {
if (strcmp(update, "force-one")==0) {
/* Not enough devices for a working array,
* so bring this one up-to-date
*/
if (sb->events != __cpu_to_le64(info->events))
rv = 1;
sb->events = __cpu_to_le64(info->events);
}
if (strcmp(update, "force-array")==0) {
/* Degraded array and 'force' requests to
* maybe need to mark it 'clean'.
*/
switch(__le32_to_cpu(sb->level)) {
case 5: case 4: case 6:
/* need to force clean */

0
tests/06update-uuid Normal file
View File