summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2008-10-15 14:15:47 -0700
committerDan Williams <dan.j.williams@intel.com>2008-10-15 14:15:47 -0700
commitc92a2527e1f36ae8e3e83e0d7ca3ed5d269906ef (patch)
treeea37971f6d5d03d46696e70270913a7beedb43aa
parent5c3db629a6e29839f82657131d8aa1d045f1fd3e (diff)
downloadmdadm-c92a2527e1f36ae8e3e83e0d7ca3ed5d269906ef.tar.gz
mdadm-c92a2527e1f36ae8e3e83e0d7ca3ed5d269906ef.tar.xz
mdadm-c92a2527e1f36ae8e3e83e0d7ca3ed5d269906ef.zip
imsm: confirm raid10 layout, fix up handling raid10 failures
1/ near-2 indeed matches how the Windows driver lays out the data 2/ update imsm_check_degraded to check for rebuilding disks in the raid10 case Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--super-intel.c41
1 files changed, 23 insertions, 18 deletions
diff --git a/super-intel.c b/super-intel.c
index eb9a9e9..e9f9099 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -678,7 +678,7 @@ static int imsm_level_to_layout(int level)
case 6:
return ALGORITHM_LEFT_ASYMMETRIC;
case 10:
- return 0x102; //FIXME is this correct?
+ return 0x102;
}
return -1;
}
@@ -2310,30 +2310,35 @@ static __u8 imsm_check_degraded(struct intel_super *super, struct imsm_dev *dev,
case 10:
{
/**
- * check to see if any mirrors have failed,
- * otherwise we are degraded
+ * check to see if any mirrors have failed, otherwise we
+ * are degraded. Even numbered slots are mirrored on
+ * slot+1
*/
- int device_per_mirror = 2; /* FIXME is this always the case?
- * and are they always adjacent?
- */
- int r10fail = 0;
int i;
+ int insync;
for (i = 0; i < map->num_members; i++) {
- int idx = get_imsm_disk_idx(dev, i);
- struct imsm_disk *disk = get_imsm_disk(super, idx);
+ __u32 ord = get_imsm_ord_tbl_ent(dev, i);
+ int idx = ord_to_idx(ord);
+ struct imsm_disk *disk;
- if (!disk)
- r10fail++;
- else if (__le32_to_cpu(disk->status) & FAILED_DISK)
- r10fail++;
+ /* reset the potential in-sync count on even-numbered
+ * slots. num_copies is always 2 for imsm raid10
+ */
+ if ((i & 1) == 0)
+ insync = 2;
- if (r10fail >= device_per_mirror)
- return IMSM_T_STATE_FAILED;
+ disk = get_imsm_disk(super, idx);
+ if (!disk ||
+ __le32_to_cpu(disk->status) & FAILED_DISK ||
+ ord & IMSM_ORD_REBUILD)
+ insync--;
- /* reset 'r10fail' for next mirror set */
- if (!((i + 1) % device_per_mirror))
- r10fail = 0;
+ /* no in-sync disks left in this mirror the
+ * array has failed
+ */
+ if (insync == 0)
+ return IMSM_T_STATE_FAILED;
}
return IMSM_T_STATE_DEGRADED;