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

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