From 326727d9c985b8f58fd53d6efcc4bd6e1721bfb5 Mon Sep 17 00:00:00 2001 From: Anna Czarnowska Date: Wed, 5 Jan 2011 14:34:14 +1100 Subject: [PATCH] Use one function chosing spares from container container_chose_spares in Monitor.c and get_spares_for_grow in super-intel.c do the same thing: search for spares in a container. Another version will also be needed for Incremental so a more general solution is presented here and applied in two previous contexts. Normally domlist==NULL would lead an empty list but this is typically checked earlier so here it is interpreted as "do not test domains". Signed-off-by: Anna Czarnowska Signed-off-by: NeilBrown --- Monitor.c | 51 +++++++++++-------------------------------- mdadm.h | 6 +++++- super-intel.c | 36 +------------------------------ util.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 74 deletions(-) diff --git a/Monitor.c b/Monitor.c index e79f658b..00db53f2 100644 --- a/Monitor.c +++ b/Monitor.c @@ -828,59 +828,34 @@ static dev_t container_choose_spare(struct state *from, struct state *to, /* This is similar to choose_spare, but we cannot trust devstate, * so we need to read the metadata instead */ - + struct mdinfo *list; struct supertype *st = from->metadata; int fd = open(from->devname, O_RDONLY); int err; - struct mdinfo *disks, *d; dev_t dev = 0; if (fd < 0) return 0; - if (!st->ss->getinfo_super_disks) + if (!st->ss->getinfo_super_disks) { + close(fd); return 0; + } err = st->ss->load_container(st, fd, NULL); close(fd); if (err) return 0; - - disks = st->ss->getinfo_super_disks(st); - st->ss->free_super(st); - - if (!disks) - return 0; - for (d = disks->devs ; d && !dev ; d = d->next) { - if (d->disk.state == 0) { - struct dev_policy *pol; - unsigned long long dev_size; - dev = makedev(d->disk.major,d->disk.minor); - - if (min_size && - dev_size_from_id(dev, &dev_size) && - dev_size < min_size) { - dev = 0; - continue; - } - if (from == to) - /* Just checking if destination already has - * a spare, no need to check policy, we are - * done. - */ - break; - - pol = devnum_policy(dev); - if (from->spare_group) - pol_add(&pol, pol_domain, - from->spare_group, NULL); - if (!domain_test(domlist, pol, to->metadata->ss->name)) - dev = 0; - - dev_policy_free(pol); - } + /* We only need one spare so full list not needed */ + list = container_choose_spares(st, min_size, domlist, from->spare_group, + to->metadata->ss->name, 1); + if (list) { + struct mdinfo *disks = list->devs; + if (disks) + dev = makedev(disks->disk.major, disks->disk.minor); + sysfs_free(list); } - sysfs_free(disks); + st->ss->free_super(st); return dev; } diff --git a/mdadm.h b/mdadm.h index d3e88bc7..e210718b 100644 --- a/mdadm.h +++ b/mdadm.h @@ -1095,7 +1095,11 @@ extern void append_metadata_update(struct supertype *st, void *buf, int len); extern int assemble_container_content(struct supertype *st, int mdfd, struct mdinfo *content, int runstop, char *chosen_name, int verbose); - +extern struct mdinfo *container_choose_spares(struct supertype *st, + unsigned long long min_size, + struct domainlist *domlist, + char *spare_group, + const char *metadata, int get_one); extern int add_disk(int mdfd, struct supertype *st, struct mdinfo *sra, struct mdinfo *info); extern int remove_disk(int mdfd, struct supertype *st, diff --git a/super-intel.c b/super-intel.c index c4100efc..dc3b03d3 100644 --- a/super-intel.c +++ b/super-intel.c @@ -6241,42 +6241,8 @@ static int imsm_reshape_is_allowed_on_container(struct supertype *st, */ static struct mdinfo *get_spares_for_grow(struct supertype *st) { - dev_t dev = 0; - struct mdinfo *disks, *d, **dp; unsigned long long min_size = min_acceptable_spare_size_imsm(st); - - /* get list of alldisks in container */ - disks = getinfo_super_disks_imsm(st); - - if (!disks) - return NULL; - /* find spare devices on the list */ - dp = &disks->devs; - disks->array.spare_disks = 0; - while (*dp) { - int found = 0; - d = *dp; - if (d->disk.state == 0) { - /* check if size is acceptable */ - unsigned long long dev_size; - dev = makedev(d->disk.major,d->disk.minor); - if (min_size && - dev_size_from_id(dev, &dev_size) && - dev_size >= min_size) { - dev = 0; - found = 1; - } - } - if (found) { - dp = &d->next; - disks->array.spare_disks++; - } else { - *dp = d->next; - d->next = NULL; - sysfs_free(d); - } - } - return disks; + return container_choose_spares(st, min_size, NULL, NULL, NULL, 0); } /****************************************************************************** diff --git a/util.c b/util.c index c4c31a31..10d21406 100644 --- a/util.c +++ b/util.c @@ -1909,3 +1909,63 @@ int experimental(void) } } +/* Pick all spares matching given criteria from a container + * if min_size == 0 do not check size + * if domlist == NULL do not check domains + * if spare_group given add it to domains of each spare + * metadata allows to test domains using metadata of destination array */ +struct mdinfo *container_choose_spares(struct supertype *st, + unsigned long long min_size, + struct domainlist *domlist, + char *spare_group, + const char *metadata, int get_one) +{ + struct mdinfo *d, **dp, *disks = NULL; + + /* get list of all disks in container */ + if (st->ss->getinfo_super_disks) + disks = st->ss->getinfo_super_disks(st); + + if (!disks) + return disks; + /* find spare devices on the list */ + dp = &disks->devs; + disks->array.spare_disks = 0; + while (*dp) { + int found = 0; + d = *dp; + if (d->disk.state == 0) { + /* check if size is acceptable */ + unsigned long long dev_size; + dev_t dev = makedev(d->disk.major,d->disk.minor); + + if (!min_size || + (dev_size_from_id(dev, &dev_size) && + dev_size >= min_size)) + found = 1; + /* check if domain matches */ + if (found && domlist) { + struct dev_policy *pol = devnum_policy(dev); + if (spare_group) + pol_add(&pol, pol_domain, + spare_group, NULL); + if (!domain_test(domlist, pol, metadata)) + found = 0; + dev_policy_free(pol); + } + } + if (found) { + dp = &d->next; + disks->array.spare_disks++; + if (get_one) { + sysfs_free(*dp); + d->next = NULL; + } + } else { + *dp = d->next; + d->next = NULL; + sysfs_free(d); + } + } + return disks; +} -- 2.39.2