summaryrefslogtreecommitdiff
path: root/Incremental.c
diff options
context:
space:
mode:
authorPrzemyslaw Czarnowski <przemyslaw.hawrylewicz.czarnowski@intel.com>2010-12-26 22:31:25 +1100
committerNeilBrown <neilb@suse.de>2010-12-26 22:31:25 +1100
commit5be68a0762f479724da5e579c2b8fbf9f6a28d6a (patch)
tree070b1776f531342557dd29a43073af573570bc1e /Incremental.c
parentcbeeb0e5f016044190c4bcc61393048536608770 (diff)
external: get number of failed disks for container
Container degradation here is defined as the number of failed disks in mostly degraded sub-array. This number is used as value for array.failed_disks and used in comparison to find best match. Signed-off-by: Przemyslaw Czarnowski <przemyslaw.hawrylewicz.czarnowski@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Incremental.c')
-rw-r--r--Incremental.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/Incremental.c b/Incremental.c
index 944ed661..6ff64f3a 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -820,6 +820,32 @@ static int count_active(struct supertype *st, struct mdinfo *sra,
return cnt;
}
+/* test if container has degraded member(s) */
+static int container_members_max_degradation(struct map_ent *map, struct map_ent *me)
+{
+ mdu_array_info_t array;
+ int afd;
+ int max_degraded = 0;
+
+ for(; map; map = map->next) {
+ if (!is_subarray(map->metadata) ||
+ devname2devnum(map->metadata+1) != me->devnum)
+ continue;
+ afd = open_dev(map->devnum);
+ if (afd < 0)
+ continue;
+ /* most accurate information regarding array degradation */
+ if (ioctl(afd, GET_ARRAY_INFO, &array) >= 0) {
+ int degraded = array.raid_disks - array.active_disks -
+ array.spare_disks;
+ if (degraded > max_degraded)
+ max_degraded = degraded;
+ }
+ close(afd);
+ }
+ return (max_degraded);
+}
+
static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
struct map_ent *target, int bare,
struct supertype *st, int verbose)
@@ -887,7 +913,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE|
GET_COMPONENT|GET_VERSION);
if (sra)
- sra->array.failed_disks = 0;
+ sra->array.failed_disks = -1;
}
if (!sra)
continue;
@@ -914,6 +940,11 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
goto next;
} else
st2 = st;
+ /* update number of failed disks for mostly degraded
+ * container member */
+ if (sra->array.failed_disks == -1)
+ sra->array.failed_disks = container_members_max_degradation(map, mp);
+
get_dev_size(dfd, NULL, &devsize);
if (st2->ss->avail_size(st2, devsize) < sra->component_size) {
if (verbose > 1)