File 0090-raid6check-get-device-ordering-correct-for-syndrome-.patch of Package mdadm.5365

From 76cd79d3d19917a3d1b08310b7351f22c16e42ab Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Thu, 16 Jul 2015 11:25:40 +1000
Subject: [PATCH 133/359] raid6check: get device ordering correct for syndrome
 calculation.
References: bsc#1081910

The order of devices used for the syndrome calculation is not
the same as the order of data in the array.
The D block immediately after Q is first, then they continue
cyclicly in raid-disk order, skipping over the P disk if it is seen.

This gets the 'check' right for all layouts other than DDF, which is
quite different.

I haven't confirmed that this does't break repair.

Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Coly Li <colyli@suse.de>

---
 raid6check.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/raid6check.c b/raid6check.c
index 86a45b6..a78ac5c 100644
--- a/raid6check.c
+++ b/raid6check.c
@@ -338,7 +338,7 @@ int check_stripes(struct mdinfo *info, int *source, unsigned long long *offsets,
 	sighandler_t *sig = xmalloc(3 * sizeof(sighandler_t));
 
 	int i, j;
-	int diskP, diskQ;
+	int diskP, diskQ, diskD;
 	int data_disks = raid_disks - 2;
 	int err = 0;
 
@@ -377,15 +377,24 @@ int check_stripes(struct mdinfo *info, int *source, unsigned long long *offsets,
 			}
 		}
 
+		diskP = geo_map(-1, start, raid_disks, level, layout);
+		diskQ = geo_map(-2, start, raid_disks, level, layout);
+		/* The syndrome-order if disks starts immediately after 'Q',
+		 * but skips P */
+		diskD = diskQ;
 		for (i = 0 ; i < data_disks ; i++) {
-			int disk = geo_map(i, start, raid_disks, level, layout);
-			blocks[i] = stripes[disk];
-			block_index_for_slot[disk] = i;
+			diskD = diskD + 1;
+			if (diskD > raid_disks)
+				diskD = 0;
+			if (diskD == diskP)
+				diskD += 1;
+			if (diskD > raid_disks)
+				diskD = 0;
+			blocks[i] = stripes[diskD];
+			block_index_for_slot[diskD] = i;
 		}
 
 		qsyndrome(p, q, (uint8_t**)blocks, data_disks, chunk_size);
-		diskP = geo_map(-1, start, raid_disks, level, layout);
-		diskQ = geo_map(-2, start, raid_disks, level, layout);
 		blocks[data_disks] = stripes[diskP];
 		block_index_for_slot[diskP] = data_disks;
 		blocks[data_disks+1] = stripes[diskQ];
-- 
2.16.1

openSUSE Build Service is sponsored by