diff options
author | NeilBrown <neilb@suse.de> | 2015-07-16 11:25:40 +1000 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2015-07-16 11:25:40 +1000 |
commit | 76cd79d3d19917a3d1b08310b7351f22c16e42ab (patch) | |
tree | 6ee0010a6f20419d33daeaeed795136ad5ab338c | |
parent | 0832fb09d91515ced206f5459f0015492b4cc10c (diff) | |
download | mdadm-76cd79d3d19917a3d1b08310b7351f22c16e42ab.tar.gz |
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 <neilb@suse.de>
-rw-r--r-- | raid6check.c | 21 |
1 files 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]; |