diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/Kconfig | 3 | ||||
-rw-r--r-- | drivers/md/raid5.c | 54 |
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 | |||
109 | config MD_RAID456 | 109 | config 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 | ||
927 | static void compute_block(struct stripe_head *sh, int dd_idx) | 927 | static 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) | |||
1132 | static void compute_block_1(struct stripe_head *sh, int dd_idx, int nozero) | 1132 | static 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 | } |