diff options
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 0a5cf2171214..54ef8d75541d 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -502,13 +502,17 @@ async_copy_data(int frombio, struct bio *bio, struct page *page, | |||
502 | int i; | 502 | int i; |
503 | int page_offset; | 503 | int page_offset; |
504 | struct async_submit_ctl submit; | 504 | struct async_submit_ctl submit; |
505 | enum async_tx_flags flags = 0; | ||
505 | 506 | ||
506 | if (bio->bi_sector >= sector) | 507 | if (bio->bi_sector >= sector) |
507 | page_offset = (signed)(bio->bi_sector - sector) * 512; | 508 | page_offset = (signed)(bio->bi_sector - sector) * 512; |
508 | else | 509 | else |
509 | page_offset = (signed)(sector - bio->bi_sector) * -512; | 510 | page_offset = (signed)(sector - bio->bi_sector) * -512; |
510 | 511 | ||
511 | init_async_submit(&submit, 0, tx, NULL, NULL, NULL); | 512 | if (frombio) |
513 | flags |= ASYNC_TX_FENCE; | ||
514 | init_async_submit(&submit, flags, tx, NULL, NULL, NULL); | ||
515 | |||
512 | bio_for_each_segment(bvl, bio, i) { | 516 | bio_for_each_segment(bvl, bio, i) { |
513 | int len = bio_iovec_idx(bio, i)->bv_len; | 517 | int len = bio_iovec_idx(bio, i)->bv_len; |
514 | int clen; | 518 | int clen; |
@@ -685,7 +689,7 @@ ops_run_compute5(struct stripe_head *sh, struct raid5_percpu *percpu) | |||
685 | 689 | ||
686 | atomic_inc(&sh->count); | 690 | atomic_inc(&sh->count); |
687 | 691 | ||
688 | init_async_submit(&submit, ASYNC_TX_XOR_ZERO_DST, NULL, | 692 | init_async_submit(&submit, ASYNC_TX_FENCE|ASYNC_TX_XOR_ZERO_DST, NULL, |
689 | ops_complete_compute, sh, to_addr_conv(sh, percpu)); | 693 | ops_complete_compute, sh, to_addr_conv(sh, percpu)); |
690 | if (unlikely(count == 1)) | 694 | if (unlikely(count == 1)) |
691 | tx = async_memcpy(xor_dest, xor_srcs[0], 0, 0, STRIPE_SIZE, &submit); | 695 | tx = async_memcpy(xor_dest, xor_srcs[0], 0, 0, STRIPE_SIZE, &submit); |
@@ -763,7 +767,8 @@ ops_run_compute6_1(struct stripe_head *sh, struct raid5_percpu *percpu) | |||
763 | count = set_syndrome_sources(blocks, sh); | 767 | count = set_syndrome_sources(blocks, sh); |
764 | blocks[count] = NULL; /* regenerating p is not necessary */ | 768 | blocks[count] = NULL; /* regenerating p is not necessary */ |
765 | BUG_ON(blocks[count+1] != dest); /* q should already be set */ | 769 | BUG_ON(blocks[count+1] != dest); /* q should already be set */ |
766 | init_async_submit(&submit, 0, NULL, ops_complete_compute, sh, | 770 | init_async_submit(&submit, ASYNC_TX_FENCE, NULL, |
771 | ops_complete_compute, sh, | ||
767 | to_addr_conv(sh, percpu)); | 772 | to_addr_conv(sh, percpu)); |
768 | tx = async_gen_syndrome(blocks, 0, count+2, STRIPE_SIZE, &submit); | 773 | tx = async_gen_syndrome(blocks, 0, count+2, STRIPE_SIZE, &submit); |
769 | } else { | 774 | } else { |
@@ -775,8 +780,8 @@ ops_run_compute6_1(struct stripe_head *sh, struct raid5_percpu *percpu) | |||
775 | blocks[count++] = sh->dev[i].page; | 780 | blocks[count++] = sh->dev[i].page; |
776 | } | 781 | } |
777 | 782 | ||
778 | init_async_submit(&submit, ASYNC_TX_XOR_ZERO_DST, NULL, | 783 | init_async_submit(&submit, ASYNC_TX_FENCE|ASYNC_TX_XOR_ZERO_DST, |
779 | ops_complete_compute, sh, | 784 | NULL, ops_complete_compute, sh, |
780 | to_addr_conv(sh, percpu)); | 785 | to_addr_conv(sh, percpu)); |
781 | tx = async_xor(dest, blocks, 0, count, STRIPE_SIZE, &submit); | 786 | tx = async_xor(dest, blocks, 0, count, STRIPE_SIZE, &submit); |
782 | } | 787 | } |
@@ -837,8 +842,9 @@ ops_run_compute6_2(struct stripe_head *sh, struct raid5_percpu *percpu) | |||
837 | /* Q disk is one of the missing disks */ | 842 | /* Q disk is one of the missing disks */ |
838 | if (faila == syndrome_disks) { | 843 | if (faila == syndrome_disks) { |
839 | /* Missing P+Q, just recompute */ | 844 | /* Missing P+Q, just recompute */ |
840 | init_async_submit(&submit, 0, NULL, ops_complete_compute, | 845 | init_async_submit(&submit, ASYNC_TX_FENCE, NULL, |
841 | sh, to_addr_conv(sh, percpu)); | 846 | ops_complete_compute, sh, |
847 | to_addr_conv(sh, percpu)); | ||
842 | return async_gen_syndrome(blocks, 0, count+2, | 848 | return async_gen_syndrome(blocks, 0, count+2, |
843 | STRIPE_SIZE, &submit); | 849 | STRIPE_SIZE, &submit); |
844 | } else { | 850 | } else { |
@@ -859,21 +865,24 @@ ops_run_compute6_2(struct stripe_head *sh, struct raid5_percpu *percpu) | |||
859 | blocks[count++] = sh->dev[i].page; | 865 | blocks[count++] = sh->dev[i].page; |
860 | } | 866 | } |
861 | dest = sh->dev[data_target].page; | 867 | dest = sh->dev[data_target].page; |
862 | init_async_submit(&submit, ASYNC_TX_XOR_ZERO_DST, NULL, | 868 | init_async_submit(&submit, |
863 | NULL, NULL, to_addr_conv(sh, percpu)); | 869 | ASYNC_TX_FENCE|ASYNC_TX_XOR_ZERO_DST, |
870 | NULL, NULL, NULL, | ||
871 | to_addr_conv(sh, percpu)); | ||
864 | tx = async_xor(dest, blocks, 0, count, STRIPE_SIZE, | 872 | tx = async_xor(dest, blocks, 0, count, STRIPE_SIZE, |
865 | &submit); | 873 | &submit); |
866 | 874 | ||
867 | count = set_syndrome_sources(blocks, sh); | 875 | count = set_syndrome_sources(blocks, sh); |
868 | init_async_submit(&submit, 0, tx, ops_complete_compute, | 876 | init_async_submit(&submit, ASYNC_TX_FENCE, tx, |
869 | sh, to_addr_conv(sh, percpu)); | 877 | ops_complete_compute, sh, |
878 | to_addr_conv(sh, percpu)); | ||
870 | return async_gen_syndrome(blocks, 0, count+2, | 879 | return async_gen_syndrome(blocks, 0, count+2, |
871 | STRIPE_SIZE, &submit); | 880 | STRIPE_SIZE, &submit); |
872 | } | 881 | } |
873 | } | 882 | } |
874 | 883 | ||
875 | init_async_submit(&submit, 0, NULL, ops_complete_compute, sh, | 884 | init_async_submit(&submit, ASYNC_TX_FENCE, NULL, ops_complete_compute, |
876 | to_addr_conv(sh, percpu)); | 885 | sh, to_addr_conv(sh, percpu)); |
877 | if (failb == syndrome_disks) { | 886 | if (failb == syndrome_disks) { |
878 | /* We're missing D+P. */ | 887 | /* We're missing D+P. */ |
879 | return async_raid6_datap_recov(syndrome_disks+2, STRIPE_SIZE, | 888 | return async_raid6_datap_recov(syndrome_disks+2, STRIPE_SIZE, |
@@ -916,7 +925,7 @@ ops_run_prexor(struct stripe_head *sh, struct raid5_percpu *percpu, | |||
916 | xor_srcs[count++] = dev->page; | 925 | xor_srcs[count++] = dev->page; |
917 | } | 926 | } |
918 | 927 | ||
919 | init_async_submit(&submit, ASYNC_TX_XOR_DROP_DST, tx, | 928 | init_async_submit(&submit, ASYNC_TX_FENCE|ASYNC_TX_XOR_DROP_DST, tx, |
920 | ops_complete_prexor, sh, to_addr_conv(sh, percpu)); | 929 | ops_complete_prexor, sh, to_addr_conv(sh, percpu)); |
921 | tx = async_xor(xor_dest, xor_srcs, 0, count, STRIPE_SIZE, &submit); | 930 | tx = async_xor(xor_dest, xor_srcs, 0, count, STRIPE_SIZE, &submit); |
922 | 931 | ||