From 14657efd3ad918f6779100e1047ea60d97a0d667 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Mon, 29 Oct 2018 20:57:17 +0800 Subject: block: make sure discard bio is aligned with logical block size commit 1adfc5e4136f5967d591c399aff95b3b035f16b7 upstream. Obviously the created discard bio has to be aligned with logical block size. This patch introduces the helper of bio_allowed_max_sectors() for this purpose. Cc: stable@vger.kernel.org Cc: Mike Snitzer Cc: Christoph Hellwig Cc: Xiao Ni Cc: Mariusz Dabrowski Fixes: 744889b7cbb56a6 ("block: don't deal with discard limit in blkdev_issue_discard()") Fixes: a22c4d7e34402cc ("block: re-add discard_granularity and alignment checks") Reported-by: Rui Salvaterra Tested-by: Rui Salvaterra Signed-off-by: Ming Lei Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- block/blk-lib.c | 3 +-- block/blk-merge.c | 3 ++- block/blk.h | 10 ++++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) (limited to 'block') diff --git a/block/blk-lib.c b/block/blk-lib.c index bbd44666f2b5..aa62201601c5 100644 --- a/block/blk-lib.c +++ b/block/blk-lib.c @@ -58,8 +58,7 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector, if (!req_sects) goto fail; - if (req_sects > UINT_MAX >> 9) - req_sects = UINT_MAX >> 9; + req_sects = min(req_sects, bio_allowed_max_sectors(q)); end_sect = sector + req_sects; diff --git a/block/blk-merge.c b/block/blk-merge.c index aaec38cc37b8..2e042190a4f1 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -27,7 +27,8 @@ static struct bio *blk_bio_discard_split(struct request_queue *q, /* Zero-sector (unknown) and one-sector granularities are the same. */ granularity = max(q->limits.discard_granularity >> 9, 1U); - max_discard_sectors = min(q->limits.max_discard_sectors, UINT_MAX >> 9); + max_discard_sectors = min(q->limits.max_discard_sectors, + bio_allowed_max_sectors(q)); max_discard_sectors -= max_discard_sectors % granularity; if (unlikely(!max_discard_sectors)) { diff --git a/block/blk.h b/block/blk.h index 9db4e389582c..977d4b5d968d 100644 --- a/block/blk.h +++ b/block/blk.h @@ -328,6 +328,16 @@ static inline unsigned long blk_rq_deadline(struct request *rq) return rq->__deadline & ~0x1UL; } +/* + * The max size one bio can handle is UINT_MAX becasue bvec_iter.bi_size + * is defined as 'unsigned int', meantime it has to aligned to with logical + * block size which is the minimum accepted unit by hardware. + */ +static inline unsigned int bio_allowed_max_sectors(struct request_queue *q) +{ + return round_down(UINT_MAX, queue_logical_block_size(q)) >> 9; +} + /* * Internal io_context interface */ -- cgit v1.2.3-55-g7522