diff options
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 7ff4f252ca1a..f8b906843926 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -778,6 +778,12 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) | |||
778 | bi->bi_io_vec[0].bv_len = STRIPE_SIZE; | 778 | bi->bi_io_vec[0].bv_len = STRIPE_SIZE; |
779 | bi->bi_io_vec[0].bv_offset = 0; | 779 | bi->bi_io_vec[0].bv_offset = 0; |
780 | bi->bi_size = STRIPE_SIZE; | 780 | bi->bi_size = STRIPE_SIZE; |
781 | /* | ||
782 | * If this is discard request, set bi_vcnt 0. We don't | ||
783 | * want to confuse SCSI because SCSI will replace payload | ||
784 | */ | ||
785 | if (rw & REQ_DISCARD) | ||
786 | bi->bi_vcnt = 0; | ||
781 | if (rrdev) | 787 | if (rrdev) |
782 | set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags); | 788 | set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags); |
783 | 789 | ||
@@ -816,6 +822,12 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) | |||
816 | rbi->bi_io_vec[0].bv_len = STRIPE_SIZE; | 822 | rbi->bi_io_vec[0].bv_len = STRIPE_SIZE; |
817 | rbi->bi_io_vec[0].bv_offset = 0; | 823 | rbi->bi_io_vec[0].bv_offset = 0; |
818 | rbi->bi_size = STRIPE_SIZE; | 824 | rbi->bi_size = STRIPE_SIZE; |
825 | /* | ||
826 | * If this is discard request, set bi_vcnt 0. We don't | ||
827 | * want to confuse SCSI because SCSI will replace payload | ||
828 | */ | ||
829 | if (rw & REQ_DISCARD) | ||
830 | rbi->bi_vcnt = 0; | ||
819 | if (conf->mddev->gendisk) | 831 | if (conf->mddev->gendisk) |
820 | trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev), | 832 | trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev), |
821 | rbi, disk_devt(conf->mddev->gendisk), | 833 | rbi, disk_devt(conf->mddev->gendisk), |
@@ -2910,6 +2922,14 @@ static void handle_stripe_clean_event(struct r5conf *conf, | |||
2910 | } | 2922 | } |
2911 | /* now that discard is done we can proceed with any sync */ | 2923 | /* now that discard is done we can proceed with any sync */ |
2912 | clear_bit(STRIPE_DISCARD, &sh->state); | 2924 | clear_bit(STRIPE_DISCARD, &sh->state); |
2925 | /* | ||
2926 | * SCSI discard will change some bio fields and the stripe has | ||
2927 | * no updated data, so remove it from hash list and the stripe | ||
2928 | * will be reinitialized | ||
2929 | */ | ||
2930 | spin_lock_irq(&conf->device_lock); | ||
2931 | remove_hash(sh); | ||
2932 | spin_unlock_irq(&conf->device_lock); | ||
2913 | if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state)) | 2933 | if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state)) |
2914 | set_bit(STRIPE_HANDLE, &sh->state); | 2934 | set_bit(STRIPE_HANDLE, &sh->state); |
2915 | 2935 | ||