Skip to content

Commit 4f679fe

Browse files
author
Ming Lei
committed
block: Introduce bio_needs_zone_write_plugging()
JIRA: https://issues.redhat.com/browse/RHEL-97177 commit f702914 Author: Damien Le Moal <dlemoal@kernel.org> Date: Wed Jun 25 18:33:24 2025 +0900 block: Introduce bio_needs_zone_write_plugging() In preparation for fixing device mapper zone write handling, introduce the inline helper function bio_needs_zone_write_plugging() to test if a BIO requires handling through zone write plugging using the function blk_zone_plug_bio(). This function returns true for any write (op_is_write(bio) == true) operation directed at a zoned block device using zone write plugging, that is, a block device with a disk that has a zone write plug hash table. This helper allows simplifying the check on entry to blk_zone_plug_bio() and used in to protect calls to it for blk-mq devices and DM devices. Fixes: f211268 ("dm: Use the block layer zone append emulation") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/r/20250625093327.548866-3-dlemoal@kernel.org Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Ming Lei <ming.lei@redhat.com>
1 parent 02fda9f commit 4f679fe

File tree

4 files changed

+63
-22
lines changed

4 files changed

+63
-22
lines changed

block/blk-mq.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3169,8 +3169,10 @@ void blk_mq_submit_bio(struct bio *bio)
31693169
if (blk_mq_attempt_bio_merge(q, bio, nr_segs))
31703170
goto queue_exit;
31713171

3172-
if (blk_queue_is_zoned(q) && blk_zone_plug_bio(bio, nr_segs))
3173-
goto queue_exit;
3172+
if (bio_needs_zone_write_plugging(bio)) {
3173+
if (blk_zone_plug_bio(bio, nr_segs))
3174+
goto queue_exit;
3175+
}
31743176

31753177
new_request:
31763178
if (rq) {

block/blk-zoned.c

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,25 +1113,7 @@ bool blk_zone_plug_bio(struct bio *bio, unsigned int nr_segs)
11131113
{
11141114
struct block_device *bdev = bio->bi_bdev;
11151115

1116-
if (!bdev->bd_disk->zone_wplugs_hash)
1117-
return false;
1118-
1119-
/*
1120-
* If the BIO already has the plugging flag set, then it was already
1121-
* handled through this path and this is a submission from the zone
1122-
* plug bio submit work.
1123-
*/
1124-
if (bio_flagged(bio, BIO_ZONE_WRITE_PLUGGING))
1125-
return false;
1126-
1127-
/*
1128-
* We do not need to do anything special for empty flush BIOs, e.g
1129-
* BIOs such as issued by blkdev_issue_flush(). The is because it is
1130-
* the responsibility of the user to first wait for the completion of
1131-
* write operations for flush to have any effect on the persistence of
1132-
* the written data.
1133-
*/
1134-
if (op_is_flush(bio->bi_opf) && !bio_sectors(bio))
1116+
if (WARN_ON_ONCE(!bdev->bd_disk->zone_wplugs_hash))
11351117
return false;
11361118

11371119
/*

drivers/md/dm.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1804,7 +1804,9 @@ static inline bool dm_zone_bio_needs_split(struct mapped_device *md,
18041804
}
18051805
static inline bool dm_zone_plug_bio(struct mapped_device *md, struct bio *bio)
18061806
{
1807-
return dm_emulate_zone_append(md) && blk_zone_plug_bio(bio, 0);
1807+
if (!bio_needs_zone_write_plugging(bio))
1808+
return false;
1809+
return blk_zone_plug_bio(bio, 0);
18081810
}
18091811

18101812
static blk_status_t __send_zone_reset_all_emulated(struct clone_info *ci,

include/linux/blkdev.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,12 +719,67 @@ static inline unsigned int disk_nr_zones(struct gendisk *disk)
719719
{
720720
return disk->nr_zones;
721721
}
722+
723+
/**
724+
* bio_needs_zone_write_plugging - Check if a BIO needs to be handled with zone
725+
* write plugging
726+
* @bio: The BIO being submitted
727+
*
728+
* Return true whenever @bio execution needs to be handled through zone
729+
* write plugging (using blk_zone_plug_bio()). Return false otherwise.
730+
*/
731+
static inline bool bio_needs_zone_write_plugging(struct bio *bio)
732+
{
733+
enum req_op op = bio_op(bio);
734+
735+
/*
736+
* Only zoned block devices have a zone write plug hash table. But not
737+
* all of them have one (e.g. DM devices may not need one).
738+
*/
739+
if (!bio->bi_bdev->bd_disk->zone_wplugs_hash)
740+
return false;
741+
742+
/* Only write operations need zone write plugging. */
743+
if (!op_is_write(op))
744+
return false;
745+
746+
/* Ignore empty flush */
747+
if (op_is_flush(bio->bi_opf) && !bio_sectors(bio))
748+
return false;
749+
750+
/* Ignore BIOs that already have been handled by zone write plugging. */
751+
if (bio_flagged(bio, BIO_ZONE_WRITE_PLUGGING))
752+
return false;
753+
754+
/*
755+
* All zone write operations must be handled through zone write plugging
756+
* using blk_zone_plug_bio().
757+
*/
758+
switch (op) {
759+
case REQ_OP_ZONE_APPEND:
760+
case REQ_OP_WRITE:
761+
case REQ_OP_WRITE_ZEROES:
762+
case REQ_OP_ZONE_FINISH:
763+
case REQ_OP_ZONE_RESET:
764+
case REQ_OP_ZONE_RESET_ALL:
765+
return true;
766+
default:
767+
return false;
768+
}
769+
}
770+
722771
bool blk_zone_plug_bio(struct bio *bio, unsigned int nr_segs);
723772
#else /* CONFIG_BLK_DEV_ZONED */
724773
static inline unsigned int disk_nr_zones(struct gendisk *disk)
725774
{
726775
return 0;
727776
}
777+
778+
static inline bool bio_needs_zone_write_plugging(struct bio *bio)
779+
{
780+
return false;
781+
}
782+
728783
static inline bool blk_zone_plug_bio(struct bio *bio, unsigned int nr_segs)
729784
{
730785
return false;

0 commit comments

Comments
 (0)