aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/Kconfig3
-rw-r--r--drivers/md/raid5.c54
2 files changed, 29 insertions, 28 deletions
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index 24d93d02a1f3..bfd9b9c6252c 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -109,7 +109,8 @@ config MD_RAID10
109config MD_RAID456 109config MD_RAID456
110 tristate "RAID-4/RAID-5/RAID-6 mode" 110 tristate "RAID-4/RAID-5/RAID-6 mode"
111 depends on BLK_DEV_MD 111 depends on BLK_DEV_MD
112 select XOR_BLOCKS 112 select ASYNC_MEMCPY
113 select ASYNC_XOR
113 ---help--- 114 ---help---
114 A RAID-5 set of N drives with a capacity of C MB per drive provides 115 A RAID-5 set of N drives with a capacity of C MB per drive provides
115 the capacity of C * (N - 1) MB, and protects against a failure 116 the capacity of C * (N - 1) MB, and protects against a failure
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 5adbe0b22684..4f51dfa8e487 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -916,25 +916,25 @@ static void copy_data(int frombio, struct bio *bio,
916 } 916 }
917} 917}
918 918
919#define check_xor() do { \ 919#define check_xor() do { \
920 if (count == MAX_XOR_BLOCKS) { \ 920 if (count == MAX_XOR_BLOCKS) { \
921 xor_blocks(count, STRIPE_SIZE, ptr); \ 921 xor_blocks(count, STRIPE_SIZE, dest, ptr);\
922 count = 1; \ 922 count = 0; \
923 } \ 923 } \
924 } while(0) 924 } while(0)
925 925
926 926
927static void compute_block(struct stripe_head *sh, int dd_idx) 927static void compute_block(struct stripe_head *sh, int dd_idx)
928{ 928{
929 int i, count, disks = sh->disks; 929 int i, count, disks = sh->disks;
930 void *ptr[MAX_XOR_BLOCKS], *p; 930 void *ptr[MAX_XOR_BLOCKS], *dest, *p;
931 931
932 PRINTK("compute_block, stripe %llu, idx %d\n", 932 PRINTK("compute_block, stripe %llu, idx %d\n",
933 (unsigned long long)sh->sector, dd_idx); 933 (unsigned long long)sh->sector, dd_idx);
934 934
935 ptr[0] = page_address(sh->dev[dd_idx].page); 935 dest = page_address(sh->dev[dd_idx].page);
936 memset(ptr[0], 0, STRIPE_SIZE); 936 memset(dest, 0, STRIPE_SIZE);
937 count = 1; 937 count = 0;
938 for (i = disks ; i--; ) { 938 for (i = disks ; i--; ) {
939 if (i == dd_idx) 939 if (i == dd_idx)
940 continue; 940 continue;
@@ -948,8 +948,8 @@ static void compute_block(struct stripe_head *sh, int dd_idx)
948 948
949 check_xor(); 949 check_xor();
950 } 950 }
951 if (count != 1) 951 if (count)
952 xor_blocks(count, STRIPE_SIZE, ptr); 952 xor_blocks(count, STRIPE_SIZE, dest, ptr);
953 set_bit(R5_UPTODATE, &sh->dev[dd_idx].flags); 953 set_bit(R5_UPTODATE, &sh->dev[dd_idx].flags);
954} 954}
955 955
@@ -957,14 +957,14 @@ static void compute_parity5(struct stripe_head *sh, int method)
957{ 957{
958 raid5_conf_t *conf = sh->raid_conf; 958 raid5_conf_t *conf = sh->raid_conf;
959 int i, pd_idx = sh->pd_idx, disks = sh->disks, count; 959 int i, pd_idx = sh->pd_idx, disks = sh->disks, count;
960 void *ptr[MAX_XOR_BLOCKS]; 960 void *ptr[MAX_XOR_BLOCKS], *dest;
961 struct bio *chosen; 961 struct bio *chosen;
962 962
963 PRINTK("compute_parity5, stripe %llu, method %d\n", 963 PRINTK("compute_parity5, stripe %llu, method %d\n",
964 (unsigned long long)sh->sector, method); 964 (unsigned long long)sh->sector, method);
965 965
966 count = 1; 966 count = 0;
967 ptr[0] = page_address(sh->dev[pd_idx].page); 967 dest = page_address(sh->dev[pd_idx].page);
968 switch(method) { 968 switch(method) {
969 case READ_MODIFY_WRITE: 969 case READ_MODIFY_WRITE:
970 BUG_ON(!test_bit(R5_UPTODATE, &sh->dev[pd_idx].flags)); 970 BUG_ON(!test_bit(R5_UPTODATE, &sh->dev[pd_idx].flags));
@@ -987,7 +987,7 @@ static void compute_parity5(struct stripe_head *sh, int method)
987 } 987 }
988 break; 988 break;
989 case RECONSTRUCT_WRITE: 989 case RECONSTRUCT_WRITE:
990 memset(ptr[0], 0, STRIPE_SIZE); 990 memset(dest, 0, STRIPE_SIZE);
991 for (i= disks; i-- ;) 991 for (i= disks; i-- ;)
992 if (i!=pd_idx && sh->dev[i].towrite) { 992 if (i!=pd_idx && sh->dev[i].towrite) {
993 chosen = sh->dev[i].towrite; 993 chosen = sh->dev[i].towrite;
@@ -1003,9 +1003,9 @@ static void compute_parity5(struct stripe_head *sh, int method)
1003 case CHECK_PARITY: 1003 case CHECK_PARITY:
1004 break; 1004 break;
1005 } 1005 }
1006 if (count>1) { 1006 if (count) {
1007 xor_blocks(count, STRIPE_SIZE, ptr); 1007 xor_blocks(count, STRIPE_SIZE, dest, ptr);
1008 count = 1; 1008 count = 0;
1009 } 1009 }
1010 1010
1011 for (i = disks; i--;) 1011 for (i = disks; i--;)
@@ -1037,9 +1037,9 @@ static void compute_parity5(struct stripe_head *sh, int method)
1037 check_xor(); 1037 check_xor();
1038 } 1038 }
1039 } 1039 }
1040 if (count != 1) 1040 if (count)
1041 xor_blocks(count, STRIPE_SIZE, ptr); 1041 xor_blocks(count, STRIPE_SIZE, dest, ptr);
1042 1042
1043 if (method != CHECK_PARITY) { 1043 if (method != CHECK_PARITY) {
1044 set_bit(R5_UPTODATE, &sh->dev[pd_idx].flags); 1044 set_bit(R5_UPTODATE, &sh->dev[pd_idx].flags);
1045 set_bit(R5_LOCKED, &sh->dev[pd_idx].flags); 1045 set_bit(R5_LOCKED, &sh->dev[pd_idx].flags);
@@ -1132,7 +1132,7 @@ static void compute_parity6(struct stripe_head *sh, int method)
1132static void compute_block_1(struct stripe_head *sh, int dd_idx, int nozero) 1132static void compute_block_1(struct stripe_head *sh, int dd_idx, int nozero)
1133{ 1133{
1134 int i, count, disks = sh->disks; 1134 int i, count, disks = sh->disks;
1135 void *ptr[MAX_XOR_BLOCKS], *p; 1135 void *ptr[MAX_XOR_BLOCKS], *dest, *p;
1136 int pd_idx = sh->pd_idx; 1136 int pd_idx = sh->pd_idx;
1137 int qd_idx = raid6_next_disk(pd_idx, disks); 1137 int qd_idx = raid6_next_disk(pd_idx, disks);
1138 1138
@@ -1143,9 +1143,9 @@ static void compute_block_1(struct stripe_head *sh, int dd_idx, int nozero)
1143 /* We're actually computing the Q drive */ 1143 /* We're actually computing the Q drive */
1144 compute_parity6(sh, UPDATE_PARITY); 1144 compute_parity6(sh, UPDATE_PARITY);
1145 } else { 1145 } else {
1146 ptr[0] = page_address(sh->dev[dd_idx].page); 1146 dest = page_address(sh->dev[dd_idx].page);
1147 if (!nozero) memset(ptr[0], 0, STRIPE_SIZE); 1147 if (!nozero) memset(dest, 0, STRIPE_SIZE);
1148 count = 1; 1148 count = 0;
1149 for (i = disks ; i--; ) { 1149 for (i = disks ; i--; ) {
1150 if (i == dd_idx || i == qd_idx) 1150 if (i == dd_idx || i == qd_idx)
1151 continue; 1151 continue;
@@ -1159,8 +1159,8 @@ static void compute_block_1(struct stripe_head *sh, int dd_idx, int nozero)
1159 1159
1160 check_xor(); 1160 check_xor();
1161 } 1161 }
1162 if (count != 1) 1162 if (count)
1163 xor_blocks(count, STRIPE_SIZE, ptr); 1163 xor_blocks(count, STRIPE_SIZE, dest, ptr);
1164 if (!nozero) set_bit(R5_UPTODATE, &sh->dev[dd_idx].flags); 1164 if (!nozero) set_bit(R5_UPTODATE, &sh->dev[dd_idx].flags);
1165 else clear_bit(R5_UPTODATE, &sh->dev[dd_idx].flags); 1165 else clear_bit(R5_UPTODATE, &sh->dev[dd_idx].flags);
1166 } 1166 }