diff options
author | Shaohua Li <shli@kernel.org> | 2013-10-19 02:50:28 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2013-10-23 21:57:36 -0400 |
commit | 37c61ff31e9b5e3fcf3cc6579f5c68f6ad40c4b1 (patch) | |
tree | 531c906f33e284c2916213fb994b632b03ab885a /drivers/md/raid5.c | |
parent | 905b0297a9533d7a6ee00a01a990456636877dd6 (diff) |
raid5: set bio bi_vcnt 0 for discard request
SCSI layer will add new payload for discard request. If two bios are merged
to one, the second bio has bi_vcnt 1 which is set in raid5. This will confuse
SCSI and cause oops.
Suitable for backport to 3.7+
Cc: stable@vger.kernel.org (v3.7+)
Reported-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: Shaohua Li <shli@fusionio.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Acked-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 7ff4f252ca1a..302d7cd2076c 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), |