dcavalca / rpms / mdadm

Forked from rpms/mdadm 3 years ago
Clone

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

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