summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2006-12-14 17:30:51 +1100
committerNeil Brown <neilb@suse.de>2006-12-14 17:30:51 +1100
commit67a8c82d6069e7cf7b3fef00d1442bb2fff6fecc (patch)
treec31f8dbcc341a199b606ee3397cbbc35dcfa2bab
parent434b77559edef7bfd3e5f5366a2a00039baf7b48 (diff)
downloadmdadm-67a8c82d6069e7cf7b3fef00d1442bb2fff6fecc.tar.gz
mdadm-67a8c82d6069e7cf7b3fef00d1442bb2fff6fecc.tar.xz
mdadm-67a8c82d6069e7cf7b3fef00d1442bb2fff6fecc.zip
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.
-rw-r--r--Assemble.c12
-rw-r--r--ChangeLog4
-rw-r--r--super0.c10
-rw-r--r--super1.c10
-rw-r--r--tests/06update-uuid0
5 files changed, 29 insertions, 7 deletions
diff --git a/Assemble.c b/Assemble.c
index 6ca54f9..23e3583 100644
--- a/Assemble.c
+++ b/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) {
diff --git a/ChangeLog b/ChangeLog
index 81d51d3..6ea0c3b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/super0.c b/super0.c
index 9e83193..2060e93 100644
--- a/super0.c
+++ b/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 */
diff --git a/super1.c b/super1.c
index c8d63cf..bf26cfa 100644
--- a/super1.c
+++ b/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 */
diff --git a/tests/06update-uuid b/tests/06update-uuid
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/06update-uuid