[PATCH 1/3] Use one function chosing spares from container

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>From 1c6a89cda7f5f4b05ca0f9760d444f6e9e877559 Mon Sep 17 00:00:00 2001
From: Anna Czarnowska <anna.czarnowska@xxxxxxxxx>
Date: Thu, 23 Dec 2010 14:51:08 +0100
Subject: [PATCH 1/3] Use one function chosing spares from container
Cc: linux-raid@xxxxxxxxxxxxxxx, Williams, Dan J <dan.j.williams@xxxxxxxxx>, Ciechanowski, Ed <ed.ciechanowski@xxxxxxxxx>

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 <anna.czarnowska@xxxxxxxxx>
---
 Monitor.c     |   51 +++++++++++++--------------------------------------
 mdadm.h       |    6 +++++-
 super-intel.c |   46 +++++++++++++++++++++++++++++++++++++---------
 3 files changed, 55 insertions(+), 48 deletions(-)

diff --git a/Monitor.c b/Monitor.c
index e79f658..428c227 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_chose_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 d3e88bc..dd5c901 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_chose_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 c4100ef..a30dfaa 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -6241,12 +6241,26 @@ 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);
+	return container_chose_spares(st, min_size, NULL, NULL, NULL, 0);
+}
+
+/* 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_chose_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 alldisks in container */
-	disks = getinfo_super_disks_imsm(st);
+	/* get list of all disks in container */
+	if (st->ss->getinfo_super_disks)
+		disks = st->ss->getinfo_super_disks(st);
 
 	if (!disks)
 		return NULL;
@@ -6259,17 +6273,31 @@ static struct mdinfo *get_spares_for_grow(struct supertype *st)
 		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;
+			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;
+				return(disks);
+			}
 		} else {
 			*dp = d->next;
 			d->next = NULL;
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux