On Wed, Aug 12, 2020 at 07:44:18AM +0800, Ming Lei wrote: > When queue_max_discard_segments(q) is 1, blk_discard_mergable() will > return false for discard request, then normal request merge is applied. > However, only queue_max_segments() is checked, so max discard segment > limit isn't respected. > > Check max discard segment limit in the request merge code for fixing > the issue. > > Discard request failure of virtio_blk is fixed. > > Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx> > Fixes: 69840466086d ("block: fix the DISCARD request merge") > Cc: Christoph Hellwig <hch@xxxxxx> > Cc: Stefano Garzarella <sgarzare@xxxxxxxxxx> > --- > block/blk-merge.c | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > > diff --git a/block/blk-merge.c b/block/blk-merge.c > index 5196dc145270..d18fb88ca8bd 100644 > --- a/block/blk-merge.c > +++ b/block/blk-merge.c > @@ -533,10 +533,16 @@ int __blk_rq_map_sg(struct request_queue *q, struct request *rq, > } > EXPORT_SYMBOL(__blk_rq_map_sg); > > +static inline unsigned int blk_rq_get_max_segments(struct request *rq) > +{ > + return req_op(rq) == REQ_OP_DISCARD ? > + queue_max_discard_segments(rq->q) : queue_max_segments(rq->q); I'd go for a good old if statement here.. Otherwise looks good: Reviewed-by: Christoph Hellwig <hch@xxxxxx>