Skip to content

Commit f702914

Browse files
damien-lemoalaxboe
authored andcommitted
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>
1 parent 3f66ccb commit f702914

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
@@ -1116,25 +1116,7 @@ bool blk_zone_plug_bio(struct bio *bio, unsigned int nr_segs)
11161116
{
11171117
struct block_device *bdev = bio->bi_bdev;
11181118

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

11401122
/*

drivers/md/dm.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1788,7 +1788,9 @@ static inline bool dm_zone_bio_needs_split(struct mapped_device *md,
17881788
}
17891789
static inline bool dm_zone_plug_bio(struct mapped_device *md, struct bio *bio)
17901790
{
1791-
return dm_emulate_zone_append(md) && blk_zone_plug_bio(bio, 0);
1791+
if (!bio_needs_zone_write_plugging(bio))
1792+
return false;
1793+
return blk_zone_plug_bio(bio, 0);
17921794
}
17931795

17941796
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
@@ -837,6 +837,55 @@ static inline unsigned int disk_nr_zones(struct gendisk *disk)
837837
{
838838
return disk->nr_zones;
839839
}
840+
841+
/**
842+
* bio_needs_zone_write_plugging - Check if a BIO needs to be handled with zone
843+
* write plugging
844+
* @bio: The BIO being submitted
845+
*
846+
* Return true whenever @bio execution needs to be handled through zone
847+
* write plugging (using blk_zone_plug_bio()). Return false otherwise.
848+
*/
849+
static inline bool bio_needs_zone_write_plugging(struct bio *bio)
850+
{
851+
enum req_op op = bio_op(bio);
852+
853+
/*
854+
* Only zoned block devices have a zone write plug hash table. But not
855+
* all of them have one (e.g. DM devices may not need one).
856+
*/
857+
if (!bio->bi_bdev->bd_disk->zone_wplugs_hash)
858+
return false;
859+
860+
/* Only write operations need zone write plugging. */
861+
if (!op_is_write(op))
862+
return false;
863+
864+
/* Ignore empty flush */
865+
if (op_is_flush(bio->bi_opf) && !bio_sectors(bio))
866+
return false;
867+
868+
/* Ignore BIOs that already have been handled by zone write plugging. */
869+
if (bio_flagged(bio, BIO_ZONE_WRITE_PLUGGING))
870+
return false;
871+
872+
/*
873+
* All zone write operations must be handled through zone write plugging
874+
* using blk_zone_plug_bio().
875+
*/
876+
switch (op) {
877+
case REQ_OP_ZONE_APPEND:
878+
case REQ_OP_WRITE:
879+
case REQ_OP_WRITE_ZEROES:
880+
case REQ_OP_ZONE_FINISH:
881+
case REQ_OP_ZONE_RESET:
882+
case REQ_OP_ZONE_RESET_ALL:
883+
return true;
884+
default:
885+
return false;
886+
}
887+
}
888+
840889
bool blk_zone_plug_bio(struct bio *bio, unsigned int nr_segs);
841890

842891
/**
@@ -866,6 +915,12 @@ static inline unsigned int disk_nr_zones(struct gendisk *disk)
866915
{
867916
return 0;
868917
}
918+
919+
static inline bool bio_needs_zone_write_plugging(struct bio *bio)
920+
{
921+
return false;
922+
}
923+
869924
static inline bool blk_zone_plug_bio(struct bio *bio, unsigned int nr_segs)
870925
{
871926
return false;

0 commit comments

Comments
 (0)