diff options
author | NeilBrown <neilb@suse.de> | 2009-10-16 01:27:34 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2009-10-16 01:27:34 -0400 |
commit | e4424fee1815f996dccd36be44d68ca160ec3e1b (patch) | |
tree | 13e67731367d28451fdb1dcfbf4e085ce236f9b9 /drivers/md/raid5.c | |
parent | 417b8d4ac868cf58d6c68f52d72f7648413e0edc (diff) |
md: fix problems with RAID6 calculations for DDF.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 25c3c29134d1..d4ce51b4d41b 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -158,11 +158,14 @@ static int raid6_idx_to_slot(int idx, struct stripe_head *sh, | |||
158 | { | 158 | { |
159 | int slot; | 159 | int slot; |
160 | 160 | ||
161 | if (sh->ddf_layout) | ||
162 | slot = (*count)++; | ||
161 | if (idx == sh->pd_idx) | 163 | if (idx == sh->pd_idx) |
162 | return syndrome_disks; | 164 | return syndrome_disks; |
163 | if (idx == sh->qd_idx) | 165 | if (idx == sh->qd_idx) |
164 | return syndrome_disks + 1; | 166 | return syndrome_disks + 1; |
165 | slot = (*count)++; | 167 | if (!sh->ddf_layout) |
168 | slot = (*count)++; | ||
166 | return slot; | 169 | return slot; |
167 | } | 170 | } |
168 | 171 | ||
@@ -727,9 +730,8 @@ static int set_syndrome_sources(struct page **srcs, struct stripe_head *sh) | |||
727 | srcs[slot] = sh->dev[i].page; | 730 | srcs[slot] = sh->dev[i].page; |
728 | i = raid6_next_disk(i, disks); | 731 | i = raid6_next_disk(i, disks); |
729 | } while (i != d0_idx); | 732 | } while (i != d0_idx); |
730 | BUG_ON(count != syndrome_disks); | ||
731 | 733 | ||
732 | return count; | 734 | return syndrome_disks; |
733 | } | 735 | } |
734 | 736 | ||
735 | static struct dma_async_tx_descriptor * | 737 | static struct dma_async_tx_descriptor * |
@@ -828,7 +830,6 @@ ops_run_compute6_2(struct stripe_head *sh, struct raid5_percpu *percpu) | |||
828 | failb = slot; | 830 | failb = slot; |
829 | i = raid6_next_disk(i, disks); | 831 | i = raid6_next_disk(i, disks); |
830 | } while (i != d0_idx); | 832 | } while (i != d0_idx); |
831 | BUG_ON(count != syndrome_disks); | ||
832 | 833 | ||
833 | BUG_ON(faila == failb); | 834 | BUG_ON(faila == failb); |
834 | if (failb < faila) | 835 | if (failb < faila) |
@@ -845,7 +846,7 @@ ops_run_compute6_2(struct stripe_head *sh, struct raid5_percpu *percpu) | |||
845 | init_async_submit(&submit, ASYNC_TX_FENCE, NULL, | 846 | init_async_submit(&submit, ASYNC_TX_FENCE, NULL, |
846 | ops_complete_compute, sh, | 847 | ops_complete_compute, sh, |
847 | to_addr_conv(sh, percpu)); | 848 | to_addr_conv(sh, percpu)); |
848 | return async_gen_syndrome(blocks, 0, count+2, | 849 | return async_gen_syndrome(blocks, 0, syndrome_disks+2, |
849 | STRIPE_SIZE, &submit); | 850 | STRIPE_SIZE, &submit); |
850 | } else { | 851 | } else { |
851 | struct page *dest; | 852 | struct page *dest; |
@@ -1935,10 +1936,15 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous) | |||
1935 | case ALGORITHM_PARITY_N: | 1936 | case ALGORITHM_PARITY_N: |
1936 | break; | 1937 | break; |
1937 | case ALGORITHM_ROTATING_N_CONTINUE: | 1938 | case ALGORITHM_ROTATING_N_CONTINUE: |
1939 | /* Like left_symmetric, but P is before Q */ | ||
1938 | if (sh->pd_idx == 0) | 1940 | if (sh->pd_idx == 0) |
1939 | i--; /* P D D D Q */ | 1941 | i--; /* P D D D Q */ |
1940 | else if (i > sh->pd_idx) | 1942 | else { |
1941 | i -= 2; /* D D Q P D */ | 1943 | /* D D Q P D */ |
1944 | if (i < sh->pd_idx) | ||
1945 | i += raid_disks; | ||
1946 | i -= (sh->pd_idx + 1); | ||
1947 | } | ||
1942 | break; | 1948 | break; |
1943 | case ALGORITHM_LEFT_ASYMMETRIC_6: | 1949 | case ALGORITHM_LEFT_ASYMMETRIC_6: |
1944 | case ALGORITHM_RIGHT_ASYMMETRIC_6: | 1950 | case ALGORITHM_RIGHT_ASYMMETRIC_6: |