]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
raid6check: get device ordering correct for syndrome calculation.
authorNeilBrown <neilb@suse.de>
Thu, 16 Jul 2015 01:25:40 +0000 (11:25 +1000)
committerNeilBrown <neilb@suse.de>
Thu, 16 Jul 2015 01:25:40 +0000 (11:25 +1000)
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>
raid6check.c

index 86a45b6fa6fa38f8a92ad9d980d07b1b5dee8ef3..a78ac5cbfd45633aee064d64b0dd166cc88d369c 100644 (file)
@@ -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];