diff options
author | Shaohua Li <shli@kernel.org> | 2013-10-19 02:50:28 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-11-12 22:05:31 -0500 |
commit | 7e44a92662ce582268c4f35e68aad1f632ada8f8 (patch) | |
tree | 9f2fa1ce56fdab09ad6035326cdce3e613809571 | |
parent | 4053771449476d9c323bd00c0c87bbd390588e55 (diff) |
raid5: set bio bi_vcnt 0 for discard request
commit 37c61ff31e9b5e3fcf3cc6579f5c68f6ad40c4b1 upstream.
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+
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-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 a35b846af4f8..279dd99bd4c8 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -668,6 +668,12 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) | |||
668 | bi->bi_io_vec[0].bv_len = STRIPE_SIZE; | 668 | bi->bi_io_vec[0].bv_len = STRIPE_SIZE; |
669 | bi->bi_io_vec[0].bv_offset = 0; | 669 | bi->bi_io_vec[0].bv_offset = 0; |
670 | bi->bi_size = STRIPE_SIZE; | 670 | bi->bi_size = STRIPE_SIZE; |
671 | /* | ||
672 | * If this is discard request, set bi_vcnt 0. We don't | ||
673 | * want to confuse SCSI because SCSI will replace payload | ||
674 | */ | ||
675 | if (rw & REQ_DISCARD) | ||
676 | bi->bi_vcnt = 0; | ||
671 | if (rrdev) | 677 | if (rrdev) |
672 | set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags); | 678 | set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags); |
673 | 679 | ||
@@ -706,6 +712,12 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) | |||
706 | rbi->bi_io_vec[0].bv_len = STRIPE_SIZE; | 712 | rbi->bi_io_vec[0].bv_len = STRIPE_SIZE; |
707 | rbi->bi_io_vec[0].bv_offset = 0; | 713 | rbi->bi_io_vec[0].bv_offset = 0; |
708 | rbi->bi_size = STRIPE_SIZE; | 714 | rbi->bi_size = STRIPE_SIZE; |
715 | /* | ||
716 | * If this is discard request, set bi_vcnt 0. We don't | ||
717 | * want to confuse SCSI because SCSI will replace payload | ||
718 | */ | ||
719 | if (rw & REQ_DISCARD) | ||
720 | rbi->bi_vcnt = 0; | ||
709 | if (conf->mddev->gendisk) | 721 | if (conf->mddev->gendisk) |
710 | trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev), | 722 | trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev), |
711 | rbi, disk_devt(conf->mddev->gendisk), | 723 | rbi, disk_devt(conf->mddev->gendisk), |