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:
parent
434b77559e
commit
67a8c82d60
12
Assemble.c
12
Assemble.c
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
10
super0.c
10
super0.c
|
@ -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 */
|
||||
|
|
10
super1.c
10
super1.c
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue