summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2015-04-08 12:04:00 +1000
committerNeilBrown <neilb@suse.de>2015-04-08 12:04:00 +1000
commit87af7267bd07599c89e3b0ef2f4ef7220640991c (patch)
tree71d8d2839e5e290bd4c25c67c04aeebd8abab1ba
parentc34fef774a9fe7a0cd048c7bf33eeafbf7054647 (diff)
downloadmdadm-87af7267bd07599c89e3b0ef2f4ef7220640991c.tar.gz
Assemble/force: make it possible to "force" a new device in a reshape.
Normally we do not "force"-assemble devices which are in the middle of recovery, as they are unlikely to have useful data. However, when a reshape increases the number of devices, the newly added devices appear to be recovering because they do not have complete data on them yet, but then they aren't expected to until the reshape completes. So in this case, it can be appropriate to force-assemble them. Reported-by: "Jonathan Harker (Jesusaurus)" <jesusaurus@gentlydownthe.net> Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--Assemble.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/Assemble.c b/Assemble.c
index 46ab72e..25a103d 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -817,12 +817,37 @@ static int force_array(struct mdinfo *content,
i < content->array.raid_disks * 2 && i < bestcnt;
i += 2) {
int j = best[i];
- if (j>=0 &&
- !devices[j].uptodate &&
- devices[j].i.recovery_start == MaxSector &&
- (chosen_drive < 0 ||
+ if (j < 0)
+ continue;
+ if (devices[j].uptodate)
+ continue;
+ if (devices[j].i.recovery_start != MaxSector) {
+ int delta;
+ if (!devices[j].i.reshape_active ||
+ devices[j].i.delta_disks <= 0)
+ continue;
+ /* When increasing number of devices, an
+ * added device also appears to be
+ * recovering. It is safe to include it
+ * as long as it won't be a source of
+ * data.
+ * For now, just allow for last data
+ * devices in RAID4 or last devices in RAID4/5/6.
+ */
+ delta = devices[j].i.delta_disks;
+ if (devices[j].i.array.level >= 4 &&
+ devices[j].i.array.level <= 6 &&
+ i/2 >= content->array.raid_disks - delta)
+ /* OK */;
+ else if (devices[j].i.array.level == 4 &&
+ i/2 >= content->array.raid_disks - delta - 1)
+ /* OK */;
+ else
+ continue;
+ }
+ if (chosen_drive < 0 ||
devices[j].i.events
- > devices[chosen_drive].i.events))
+ > devices[chosen_drive].i.events)
chosen_drive = j;
}
if (chosen_drive < 0)