|
|
2c1b57 |
commit 8b9cd157dc030924afaeb1dd1a4d3306f5bda118
|
|
|
2c1b57 |
Author: Maksymilian Kunt <maksymilian.kunt@intel.com>
|
|
|
2c1b57 |
Date: Mon Nov 13 12:30:49 2017 +0100
|
|
|
2c1b57 |
|
|
|
2c1b57 |
imsm: continue resync on 3-disk RAID10
|
|
|
2c1b57 |
|
|
|
2c1b57 |
If RAID10 gets degraded during resync and is stopped, it doesn't continue
|
|
|
2c1b57 |
resync after automatic assemble and it is reported to be in sync. Resync
|
|
|
2c1b57 |
is blocked because the disk is missing. It should not happen for RAID10 as
|
|
|
2c1b57 |
it can still continue with 3 disks.
|
|
|
2c1b57 |
|
|
|
2c1b57 |
Count missing disks. Block resync only if number of missing disks exceeds
|
|
|
2c1b57 |
limit for given RAID level (only different for RAID10). Check if the
|
|
|
2c1b57 |
disk under recovery is present. If not, resync should be allowed to run.
|
|
|
2c1b57 |
|
|
|
2c1b57 |
Signed-off-by: Maksymilian Kunt <maksymilian.kunt@intel.com>
|
|
|
2c1b57 |
Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
|
|
|
2c1b57 |
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
|
|
|
2c1b57 |
|
|
|
2c1b57 |
diff --git a/super-intel.c b/super-intel.c
|
|
|
2c1b57 |
index 2f912f2..c55802f 100644
|
|
|
2c1b57 |
--- a/super-intel.c
|
|
|
2c1b57 |
+++ b/super-intel.c
|
|
|
2c1b57 |
@@ -1342,6 +1342,20 @@ static unsigned long long round_size_to_mb(unsigned long long size, unsigned int
|
|
|
2c1b57 |
return size;
|
|
|
2c1b57 |
}
|
|
|
2c1b57 |
|
|
|
2c1b57 |
+static int able_to_resync(int raid_level, int missing_disks)
|
|
|
2c1b57 |
+{
|
|
|
2c1b57 |
+ int max_missing_disks = 0;
|
|
|
2c1b57 |
+
|
|
|
2c1b57 |
+ switch (raid_level) {
|
|
|
2c1b57 |
+ case 10:
|
|
|
2c1b57 |
+ max_missing_disks = 1;
|
|
|
2c1b57 |
+ break;
|
|
|
2c1b57 |
+ default:
|
|
|
2c1b57 |
+ max_missing_disks = 0;
|
|
|
2c1b57 |
+ }
|
|
|
2c1b57 |
+ return missing_disks <= max_missing_disks;
|
|
|
2c1b57 |
+}
|
|
|
2c1b57 |
+
|
|
|
2c1b57 |
/* try to determine how much space is reserved for metadata from
|
|
|
2c1b57 |
* the last get_extents() entry on the smallest active disk,
|
|
|
2c1b57 |
* otherwise fallback to the default
|
|
|
2c1b57 |
@@ -7645,6 +7659,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
|
|
|
2c1b57 |
int slot;
|
|
|
2c1b57 |
int chunk;
|
|
|
2c1b57 |
char *ep;
|
|
|
2c1b57 |
+ int level;
|
|
|
2c1b57 |
|
|
|
2c1b57 |
if (subarray &&
|
|
|
2c1b57 |
(i != strtoul(subarray, &ep, 10) || *ep != '\0'))
|
|
|
2c1b57 |
@@ -7653,6 +7668,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
|
|
|
2c1b57 |
dev = get_imsm_dev(super, i);
|
|
|
2c1b57 |
map = get_imsm_map(dev, MAP_0);
|
|
|
2c1b57 |
map2 = get_imsm_map(dev, MAP_1);
|
|
|
2c1b57 |
+ level = get_imsm_raid_level(map);
|
|
|
2c1b57 |
|
|
|
2c1b57 |
/* do not publish arrays that are in the middle of an
|
|
|
2c1b57 |
* unsupported migration
|
|
|
2c1b57 |
@@ -7675,8 +7691,8 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
|
|
|
2c1b57 |
chunk = __le16_to_cpu(map->blocks_per_strip) >> 1;
|
|
|
2c1b57 |
/* mdadm does not support all metadata features- set the bit in all arrays state */
|
|
|
2c1b57 |
if (!validate_geometry_imsm_orom(super,
|
|
|
2c1b57 |
- get_imsm_raid_level(map), /* RAID level */
|
|
|
2c1b57 |
- imsm_level_to_layout(get_imsm_raid_level(map)),
|
|
|
2c1b57 |
+ level, /* RAID level */
|
|
|
2c1b57 |
+ imsm_level_to_layout(level),
|
|
|
2c1b57 |
map->num_members, /* raid disks */
|
|
|
2c1b57 |
&chunk, join_u32(dev->size_low, dev->size_high),
|
|
|
2c1b57 |
1 /* verbose */)) {
|
|
|
2c1b57 |
@@ -7700,6 +7716,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
|
|
|
2c1b57 |
int idx;
|
|
|
2c1b57 |
int skip;
|
|
|
2c1b57 |
__u32 ord;
|
|
|
2c1b57 |
+ int missing = 0;
|
|
|
2c1b57 |
|
|
|
2c1b57 |
skip = 0;
|
|
|
2c1b57 |
idx = get_imsm_disk_idx(dev, slot, MAP_0);
|
|
|
2c1b57 |
@@ -7713,19 +7730,27 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
|
|
|
2c1b57 |
skip = 1;
|
|
|
2c1b57 |
if (d && is_failed(&d->disk))
|
|
|
2c1b57 |
skip = 1;
|
|
|
2c1b57 |
- if (ord & IMSM_ORD_REBUILD)
|
|
|
2c1b57 |
+ if (!skip && (ord & IMSM_ORD_REBUILD))
|
|
|
2c1b57 |
recovery_start = 0;
|
|
|
2c1b57 |
|
|
|
2c1b57 |
/*
|
|
|
2c1b57 |
* if we skip some disks the array will be assmebled degraded;
|
|
|
2c1b57 |
* reset resync start to avoid a dirty-degraded
|
|
|
2c1b57 |
* situation when performing the intial sync
|
|
|
2c1b57 |
- *
|
|
|
2c1b57 |
- * FIXME handle dirty degraded
|
|
|
2c1b57 |
*/
|
|
|
2c1b57 |
- if ((skip || recovery_start == 0) &&
|
|
|
2c1b57 |
- !(dev->vol.dirty & RAIDVOL_DIRTY))
|
|
|
2c1b57 |
- this->resync_start = MaxSector;
|
|
|
2c1b57 |
+ if (skip)
|
|
|
2c1b57 |
+ missing++;
|
|
|
2c1b57 |
+
|
|
|
2c1b57 |
+ if (!(dev->vol.dirty & RAIDVOL_DIRTY)) {
|
|
|
2c1b57 |
+ if ((!able_to_resync(level, missing) ||
|
|
|
2c1b57 |
+ recovery_start == 0))
|
|
|
2c1b57 |
+ this->resync_start = MaxSector;
|
|
|
2c1b57 |
+ } else {
|
|
|
2c1b57 |
+ /*
|
|
|
2c1b57 |
+ * FIXME handle dirty degraded
|
|
|
2c1b57 |
+ */
|
|
|
2c1b57 |
+ }
|
|
|
2c1b57 |
+
|
|
|
2c1b57 |
if (skip)
|
|
|
2c1b57 |
continue;
|
|
|
2c1b57 |
|