Blame SOURCES/0022-imsm-fix-spare-activation-for-old-matrix-arrays.patch

6e099e
From 05501181f18cdccdb0b3cec1d8cf59f0995504d7 Mon Sep 17 00:00:00 2001
6e099e
From: Pawel Baldysiak <pawel.baldysiak@intel.com>
6e099e
Date: Fri, 8 Mar 2019 12:19:11 +0100
6e099e
Subject: [RHEL7.8 PATCH V2 22/47] imsm: fix spare activation for old matrix
6e099e
 arrays
6e099e
6e099e
During spare activation get_extents() calculates metadata reserved space based
6e099e
on smallest active RAID member or it will take the defaults. Since patch
6e099e
611d9529("imsm: change reserved space to 4MB") default is extended.  If array
6e099e
was created prior that patch, reserved space is smaller. In case of matrix
6e099e
RAID - spare is activated in each array one-by-one, so it is spare for first
6e099e
activation, but treated as "active" during second one.
6e099e
6e099e
In case of adding spare drive to old matrix RAID with the size the same as
6e099e
already existing member drive the routine will take the defaults during second
6e099e
run and mdmon will refuse to rebuild second volume, claiming that the drive
6e099e
does not have enough free space.
6e099e
6e099e
Add parameter to get_extents(), so the during spare activation reserved space
6e099e
is always based on smallest active drive - even if given drive is already
6e099e
active in some other array of matrix RAID.
6e099e
6e099e
Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
6e099e
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
6e099e
---
6e099e
 super-intel.c | 19 ++++++++++---------
6e099e
 1 file changed, 10 insertions(+), 9 deletions(-)
6e099e
6e099e
diff --git a/super-intel.c b/super-intel.c
6e099e
index c399433..5a7c9f8 100644
6e099e
--- a/super-intel.c
6e099e
+++ b/super-intel.c
6e099e
@@ -1313,7 +1313,8 @@ static unsigned long long per_dev_array_size(struct imsm_map *map)
6e099e
 	return array_size;
6e099e
 }
6e099e
 
6e099e
-static struct extent *get_extents(struct intel_super *super, struct dl *dl)
6e099e
+static struct extent *get_extents(struct intel_super *super, struct dl *dl,
6e099e
+				  int get_minimal_reservation)
6e099e
 {
6e099e
 	/* find a list of used extents on the given physical device */
6e099e
 	struct extent *rv, *e;
6e099e
@@ -1325,7 +1326,7 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl)
6e099e
 	 * regardless of whether the OROM has assigned sectors from the
6e099e
 	 * IMSM_RESERVED_SECTORS region
6e099e
 	 */
6e099e
-	if (dl->index == -1)
6e099e
+	if (dl->index == -1 || get_minimal_reservation)
6e099e
 		reservation = imsm_min_reserved_sectors(super);
6e099e
 	else
6e099e
 		reservation = MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS;
6e099e
@@ -1386,7 +1387,7 @@ static __u32 imsm_reserved_sectors(struct intel_super *super, struct dl *dl)
6e099e
 	if (dl->index == -1)
6e099e
 		return MPB_SECTOR_CNT;
6e099e
 
6e099e
-	e = get_extents(super, dl);
6e099e
+	e = get_extents(super, dl, 0);
6e099e
 	if (!e)
6e099e
 		return MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS;
6e099e
 
6e099e
@@ -1478,7 +1479,7 @@ static __u32 imsm_min_reserved_sectors(struct intel_super *super)
6e099e
 		return rv;
6e099e
 
6e099e
 	/* find last lba used by subarrays on the smallest active disk */
6e099e
-	e = get_extents(super, dl_min);
6e099e
+	e = get_extents(super, dl_min, 0);
6e099e
 	if (!e)
6e099e
 		return rv;
6e099e
 	for (i = 0; e[i].size; i++)
6e099e
@@ -1519,7 +1520,7 @@ int get_spare_criteria_imsm(struct supertype *st, struct spare_criteria *c)
6e099e
 	if (!dl)
6e099e
 		return -EINVAL;
6e099e
 	/* find last lba used by subarrays */
6e099e
-	e = get_extents(super, dl);
6e099e
+	e = get_extents(super, dl, 0);
6e099e
 	if (!e)
6e099e
 		return -EINVAL;
6e099e
 	for (i = 0; e[i].size; i++)
6e099e
@@ -7203,7 +7204,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
6e099e
 
6e099e
 			pos = 0;
6e099e
 			i = 0;
6e099e
-			e = get_extents(super, dl);
6e099e
+			e = get_extents(super, dl, 0);
6e099e
 			if (!e) continue;
6e099e
 			do {
6e099e
 				unsigned long long esize;
6e099e
@@ -7261,7 +7262,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
6e099e
 	}
6e099e
 
6e099e
 	/* retrieve the largest free space block */
6e099e
-	e = get_extents(super, dl);
6e099e
+	e = get_extents(super, dl, 0);
6e099e
 	maxsize = 0;
6e099e
 	i = 0;
6e099e
 	if (e) {
6e099e
@@ -7359,7 +7360,7 @@ static int imsm_get_free_size(struct supertype *st, int raiddisks,
6e099e
 		if (super->orom && dl->index < 0 && mpb->num_raid_devs)
6e099e
 			continue;
6e099e
 
6e099e
-		e = get_extents(super, dl);
6e099e
+		e = get_extents(super, dl, 0);
6e099e
 		if (!e)
6e099e
 			continue;
6e099e
 		for (i = 1; e[i-1].size; i++)
6e099e
@@ -8846,7 +8847,7 @@ static struct dl *imsm_add_spare(struct intel_super *super, int slot,
6e099e
 		/* Does this unused device have the requisite free space?
6e099e
 		 * It needs to be able to cover all member volumes
6e099e
 		 */
6e099e
-		ex = get_extents(super, dl);
6e099e
+		ex = get_extents(super, dl, 1);
6e099e
 		if (!ex) {
6e099e
 			dprintf("cannot get extents\n");
6e099e
 			continue;
6e099e
-- 
6e099e
2.7.5
6e099e