From: NeilBrown Date: Thu, 16 Jul 2015 01:25:40 +0000 (+1000) Subject: raid6check: get device ordering correct for syndrome calculation. X-Git-Tag: mdadm-3.3.3~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=76cd79d3d19917a3d1b08310b7351f22c16e42ab;p=thirdparty%2Fmdadm.git raid6check: get device ordering correct for syndrome calculation. 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 --- diff --git a/raid6check.c b/raid6check.c index 86a45b6f..a78ac5cb 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];