At least the SCSI disk driver is "benevolent" when it try to decide whether the device actually supports write zeroes, i.e. unless the device explicity report otherwise, it assumes it does at first. Therefore before we pile up bios that would fail at the end, we try the command/request once, as not doing so could trigger quite a disaster in at least certain case. For example, the host controller can be messed up entirely when one does `blkdiscard -z` a UAS drive. Signed-off-by: Tom Yan <tom.ty89@xxxxxxxxx> --- block/blk-lib.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/block/blk-lib.c b/block/blk-lib.c index e90614fd8d6a..c1e9388a8fb8 100644 --- a/block/blk-lib.c +++ b/block/blk-lib.c @@ -250,6 +250,7 @@ static int __blkdev_issue_write_zeroes(struct block_device *bdev, struct bio *bio = *biop; unsigned int max_write_zeroes_sectors; struct request_queue *q = bdev_get_queue(bdev); + int i = 0; if (!q) return -ENXIO; @@ -264,7 +265,17 @@ static int __blkdev_issue_write_zeroes(struct block_device *bdev, return -EOPNOTSUPP; while (nr_sects) { - bio = blk_next_bio(bio, 0, gfp_mask); + if (i != 1) { + bio = blk_next_bio(bio, 0, gfp_mask); + } else { + submit_bio_wait(bio); + bio_put(bio); + + if (bdev_write_zeroes_sectors(bdev) == 0) + return -EOPNOTSUPP; + else + bio = bio_alloc(gfp_mask, 0); + } bio->bi_iter.bi_sector = sector; bio_set_dev(bio, bdev); bio->bi_opf = REQ_OP_WRITE_ZEROES; @@ -280,6 +291,7 @@ static int __blkdev_issue_write_zeroes(struct block_device *bdev, nr_sects = 0; } cond_resched(); + i++; } *biop = bio; -- 2.29.2