bio_split_io_at() fails a bio that it can't split into a valid request with -EINVAL: a bio may have too many discontiguous segments for the queue, may have virtual boundary gaps that leave it without a block sized split, and now that the split size is rounded down to the data unit size of an encryption context, it may have a data unit that does not fit in the room that the queue limits leave for the split. Nothing else says which queue limit caused the failure, and a limit that is smaller than the data unit size, e.g. a max_sectors_kb that was lowered below it, is accepted by the block layer, so warn about it, with the bytes that fit and the alignment involved. Signed-off-by: Baokun Li --- block/blk-merge.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/block/blk-merge.c b/block/blk-merge.c index f92460c283e7..9bcc9c52eea1 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -349,6 +349,7 @@ int bio_split_io_at(struct bio *bio, const struct queue_limits *lim, struct bio_crypt_ctx *bc = bio_crypt_ctx(bio); struct bio_vec bv, bvprv, *bvprvp = NULL; unsigned nsegs = 0, bytes = 0, gaps = 0; + unsigned int align, split_bytes; struct bvec_iter iter; unsigned start_align_mask = lim->dma_alignment; @@ -409,14 +410,20 @@ int bio_split_io_at(struct bio *bio, const struct queue_limits *lim, * we do not use the full hardware limits. * * It is possible to submit a bio that can't be split into a valid io: - * there may either be too many discontiguous vectors for the max - * segments limit, or contain virtual boundary gaps without having a - * valid block sized split. A zero byte result means one of those - * conditions occured. + * it may have too many discontiguous vectors for the max segments + * limit, contain virtual boundary gaps without having a valid block + * sized split, or have a crypto context whose data units are larger + * than the number of bytes that fit. A zero byte result means one of + * those conditions occurred. */ - bytes = ALIGN_DOWN(bytes, bio_split_alignment(bio, lim)); - if (!bytes) + align = bio_split_alignment(bio, lim); + split_bytes = ALIGN_DOWN(bytes, align); + if (!split_bytes) { + pr_warn_ratelimited("%pg: split needs %u align, %u bytes fit\n", + bio->bi_bdev, align, bytes); return -EINVAL; + } + bytes = split_bytes; /* * Bio splitting may cause subtle trouble such as hang when doing sync -- 2.43.7