In preparation for fixing device mapper zone write handling, introduce the helper function bio_needs_zone_write_plugging() to test if a BIO requires handling through zone write plugging. This function returns true for any write operation to a zoned block device. For zone append opertions, true is returned only if the device requires zone append emulation with regular writes.
Fixes: f211268ed1f9 ("dm: Use the block layer zone append emulation") Cc: sta...@vger.kernel.org Signed-off-by: Damien Le Moal <dlem...@kernel.org> --- block/blk-zoned.c | 40 ++++++++++++++++++++++++++++++++++++++++ include/linux/blkdev.h | 9 +++++++++ 2 files changed, 49 insertions(+) diff --git a/block/blk-zoned.c b/block/blk-zoned.c index 55e64ca869d7..9d38b94cad0d 100644 --- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -1129,6 +1129,46 @@ static void blk_zone_wplug_handle_native_zone_append(struct bio *bio) disk_put_zone_wplug(zwplug); } +/** + * bio_needs_zone_write_plugging - Check if a BIO needs to be handled with zone + * write plugging + * @bio: The BIO being submitted + * + * Return true whenever @bio execution needs to be handled through zone + * write plugging. Return false otherwise. + */ +bool bio_needs_zone_write_plugging(struct bio *bio) +{ + enum req_op op = bio_op(bio); + + if (!bdev_is_zoned(bio->bi_bdev) || !op_is_write(op)) + return false; + + /* Already handled ? */ + if (bio_flagged(bio, BIO_ZONE_WRITE_PLUGGING)) + return false; + + /* Ignore empty flush */ + if (op_is_flush(bio->bi_opf) && !bio_sectors(bio)) + return false; + + /* + * Regular writes and write zeroes need to be handled through zone + * write plugging. Zone append operations only need zone write plugging + * if they are emulated. + */ + switch (op) { + case REQ_OP_ZONE_APPEND: + return bdev_emulates_zone_append(bio->bi_bdev); + case REQ_OP_WRITE: + case REQ_OP_WRITE_ZEROES: + return true; + default: + return false; + } +} +EXPORT_SYMBOL_GPL(bio_needs_zone_write_plugging); + /** * blk_zone_plug_bio - Handle a zone write BIO with zone write plugging * @bio: The BIO being submitted diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index c2b3ddea8b6d..d455057bfaa3 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -848,6 +848,9 @@ static inline unsigned int disk_nr_zones(struct gendisk *disk) { return disk->nr_zones; } + +bool bio_needs_zone_write_plugging(struct bio *bio); + bool blk_zone_plug_bio(struct bio *bio, unsigned int nr_segs); /** @@ -877,6 +880,12 @@ static inline unsigned int disk_nr_zones(struct gendisk *disk) { return 0; } + +static inline bool bio_needs_zone_write_plugging(struct bio *bio) +{ + return false; +} + static inline bool blk_zone_plug_bio(struct bio *bio, unsigned int nr_segs) { return false; -- 2.49.0