summaryrefslogtreecommitdiffstats
path: root/restripe.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2009-10-16 17:50:06 +1100
committerNeilBrown <neilb@suse.de>2009-10-16 17:50:06 +1100
commit1eac9f8454a9a057edf4bf00165728e5fbb1d8b1 (patch)
treede105dfe91150e719799cddd18eb003866052f01 /restripe.c
parent4180aa4d4e73eea810d51604e6e558a973cf1979 (diff)
downloadmdadm-1eac9f8454a9a057edf4bf00165728e5fbb1d8b1.tar.gz
mdadm-1eac9f8454a9a057edf4bf00165728e5fbb1d8b1.tar.xz
mdadm-1eac9f8454a9a057edf4bf00165728e5fbb1d8b1.zip
restripe: fix assignment of raid6 blocks for syndrome calculation.
Particularly for the _6 style. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'restripe.c')
-rw-r--r--restripe.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/restripe.c b/restripe.c
index 3d4d1c6..f673206 100644
--- a/restripe.c
+++ b/restripe.c
@@ -482,22 +482,33 @@ int save_stripes(int *source, unsigned long long *offsets,
} else {
/* for md, q is over 'data_disks' blocks,
* starting immediately after 'q'
+ * Note that for the '_6' variety, the p block
+ * makes a hole that we need to be careful of.
*/
- for (i = 0; i < data_disks; i++) {
- int dnum = geo_map(i,
- start/chunk_size/data_disks,
- raid_disks, level, layout);
- int snum;
+ int j;
+ int snum = 0;
+ for (j = 0; j < raid_disks; j++) {
+ int dnum = (qdisk + 1 + j) % raid_disks;
+ if (dnum == disk || dnum == qdisk)
+ continue;
+ for (i = 0; i < data_disks; i++)
+ if (geo_map(i,
+ start/chunk_size/data_disks,
+ raid_disks, level, layout) == dnum)
+ break;
/* i is the logical block number, so is index to 'buf'.
* dnum is physical disk number
* snum is syndrome disk for which 0 is immediately after Q
*/
- snum = (raid_disks + dnum - qdisk - 1) % raid_disks;
bufs[snum] = (uint8_t*)buf + chunk_size * i;
+
+ if (fblock[0] == i)
+ fdisk[0] = snum;
+ if (fblock[1] == i)
+ fdisk[1] = snum;
+ snum++;
}
- fdisk[0] = (raid_disks + fdisk[0] - qdisk - 1) % raid_disks;
- fdisk[1] = (raid_disks + fdisk[1] - qdisk - 1) % raid_disks;
syndrome_disks = data_disks;
}