Blame SOURCES/0025-imsm-block-changing-slots-during-creation.patch

c0f891
From 9a7df595bbe360132cb37c8b39aa1fd9ac24b43f Mon Sep 17 00:00:00 2001
c0f891
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
c0f891
Date: Tue, 21 Jun 2022 00:10:43 +0800
c0f891
Subject: [PATCH 25/52] imsm: block changing slots during creation
c0f891
c0f891
If user specifies drives for array creation, then slot order across
c0f891
volumes is not preserved.
c0f891
Ideally, it should be checked in validate_geometry() but it is not
c0f891
possible in current implementation (order is determined later).
c0f891
Add verification in add_to_super_imsm_volume() and throw error if
c0f891
mismatch is detected.
c0f891
IMSM allows to use only same members within container.
c0f891
This is not hardware dependency but metadata limitation.
c0f891
Therefore, 09-imsm-overlap test is removed. Testing it is pointless.
c0f891
After this patch, creation in this scenario is blocked. Offset
c0f891
verification is covered in other tests.
c0f891
c0f891
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
c0f891
Acked-by: Coly Li <colyli@suse.de>
c0f891
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
c0f891
---
c0f891
 super-intel.c        | 33 ++++++++++++++++++++++-----------
c0f891
 tests/09imsm-overlap | 28 ----------------------------
c0f891
 2 files changed, 22 insertions(+), 39 deletions(-)
c0f891
 delete mode 100644 tests/09imsm-overlap
c0f891
c0f891
diff --git a/super-intel.c b/super-intel.c
c0f891
index deef7c87..8ffe485c 100644
c0f891
--- a/super-intel.c
c0f891
+++ b/super-intel.c
c0f891
@@ -5789,6 +5789,10 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
c0f891
 	struct imsm_map *map;
c0f891
 	struct dl *dl, *df;
c0f891
 	int slot;
c0f891
+	int autolayout = 0;
c0f891
+
c0f891
+	if (!is_fd_valid(fd))
c0f891
+		autolayout = 1;
c0f891
 
c0f891
 	dev = get_imsm_dev(super, super->current_vol);
c0f891
 	map = get_imsm_map(dev, MAP_0);
c0f891
@@ -5799,25 +5803,32 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
c0f891
 		return 1;
c0f891
 	}
c0f891
 
c0f891
-	if (!is_fd_valid(fd)) {
c0f891
-		/* we're doing autolayout so grab the pre-marked (in
c0f891
-		 * validate_geometry) raid_disk
c0f891
-		 */
c0f891
-		for (dl = super->disks; dl; dl = dl->next)
c0f891
+	for (dl = super->disks; dl ; dl = dl->next) {
c0f891
+		if (autolayout) {
c0f891
 			if (dl->raiddisk == dk->raid_disk)
c0f891
 				break;
c0f891
-	} else {
c0f891
-		for (dl = super->disks; dl ; dl = dl->next)
c0f891
-			if (dl->major == dk->major &&
c0f891
-			    dl->minor == dk->minor)
c0f891
-				break;
c0f891
+		} else if (dl->major == dk->major && dl->minor == dk->minor)
c0f891
+			break;
c0f891
 	}
c0f891
 
c0f891
 	if (!dl) {
c0f891
-		pr_err("%s is not a member of the same container\n", devname);
c0f891
+		if (!autolayout)
c0f891
+			pr_err("%s is not a member of the same container.\n",
c0f891
+			       devname);
c0f891
 		return 1;
c0f891
 	}
c0f891
 
c0f891
+	if (!autolayout && super->current_vol > 0) {
c0f891
+		int _slot = get_disk_slot_in_dev(super, 0, dl->index);
c0f891
+
c0f891
+		if (_slot != dk->raid_disk) {
c0f891
+			pr_err("Member %s is in %d slot for the first volume, but is in %d slot for a new volume.\n",
c0f891
+			       dl->devname, _slot, dk->raid_disk);
c0f891
+			pr_err("Raid members are in different order than for the first volume, aborting.\n");
c0f891
+			return 1;
c0f891
+		}
c0f891
+	}
c0f891
+
c0f891
 	if (mpb->num_disks == 0)
c0f891
 		if (!get_dev_sector_size(dl->fd, dl->devname,
c0f891
 					 &super->sector_size))
c0f891
diff --git a/tests/09imsm-overlap b/tests/09imsm-overlap
c0f891
deleted file mode 100644
c0f891
index ff5d2093..00000000
c0f891
--- a/tests/09imsm-overlap
c0f891
+++ /dev/null
c0f891
@@ -1,28 +0,0 @@
c0f891
-
c0f891
-. tests/env-imsm-template
c0f891
-
c0f891
-# create raid arrays with varying degress of overlap
c0f891
-mdadm -CR $container -e imsm -n 6 $dev0 $dev1 $dev2 $dev3 $dev4 $dev5
c0f891
-imsm_check container 6
c0f891
-
c0f891
-size=1024
c0f891
-level=1
c0f891
-num_disks=2
c0f891
-mdadm -CR $member0 $dev0 $dev1 -n $num_disks -l $level -z $size
c0f891
-mdadm -CR $member1 $dev1 $dev2 -n $num_disks -l $level -z $size
c0f891
-mdadm -CR $member2 $dev2 $dev3 -n $num_disks -l $level -z $size
c0f891
-mdadm -CR $member3 $dev3 $dev4 -n $num_disks -l $level -z $size
c0f891
-mdadm -CR $member4 $dev4 $dev5 -n $num_disks -l $level -z $size
c0f891
-
c0f891
-udevadm settle
c0f891
-
c0f891
-offset=0
c0f891
-imsm_check member $member0 $num_disks $level $size 1024 $offset
c0f891
-offset=$((offset+size+4096))
c0f891
-imsm_check member $member1 $num_disks $level $size 1024 $offset
c0f891
-offset=$((offset+size+4096))
c0f891
-imsm_check member $member2 $num_disks $level $size 1024 $offset
c0f891
-offset=$((offset+size+4096))
c0f891
-imsm_check member $member3 $num_disks $level $size 1024 $offset
c0f891
-offset=$((offset+size+4096))
c0f891
-imsm_check member $member4 $num_disks $level $size 1024 $offset
c0f891
-- 
c0f891
2.31.1
c0f891