aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2009-10-16 01:27:34 -0400
committerNeilBrown <neilb@suse.de>2009-10-16 01:27:34 -0400
commite4424fee1815f996dccd36be44d68ca160ec3e1b (patch)
tree13e67731367d28451fdb1dcfbf4e085ce236f9b9 /drivers/md
parent417b8d4ac868cf58d6c68f52d72f7648413e0edc (diff)
md: fix problems with RAID6 calculations for DDF.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/raid5.c20
-rw-r--r--drivers/md/raid5.h2
2 files changed, 14 insertions, 8 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
735static struct dma_async_tx_descriptor * 737static 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:
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
index dcefdc9629ee..dd708359b451 100644
--- a/drivers/md/raid5.h
+++ b/drivers/md/raid5.h
@@ -488,7 +488,7 @@ static inline int algorithm_valid_raid6(int layout)
488{ 488{
489 return (layout >= 0 && layout <= 5) 489 return (layout >= 0 && layout <= 5)
490 || 490 ||
491 (layout == 8 || layout == 10) 491 (layout >= 8 && layout <= 10)
492 || 492 ||
493 (layout >= 16 && layout <= 20); 493 (layout >= 16 && layout <= 20);
494} 494}