Skip to content

Commit 8263f32

Browse files
damien-lemoalgregkh
authored andcommitted
block: Introduce bio_needs_zone_write_plugging()
commit f702914 upstream. 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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 2214b5d commit 8263f32

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
@@ -3114,8 +3114,10 @@ void blk_mq_submit_bio(struct bio *bio)
31143114
if (blk_mq_attempt_bio_merge(q, bio, nr_segs))
31153115
goto queue_exit;
31163116

3117-
if (blk_queue_is_zoned(q) && blk_zone_plug_bio(bio, nr_segs))
3118-
goto queue_exit;
3117+
if (bio_needs_zone_write_plugging(bio)) {
3118+
if (blk_zone_plug_bio(bio, nr_segs))
3119+
goto queue_exit;
3120+
}
31193121

31203122
new_request:
31213123
if (!rq) {

block/blk-zoned.c

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

1134-
if (!bdev->bd_disk->zone_wplugs_hash)
1135-
return false;
1136-
1137-
/*
1138-
* If the BIO already has the plugging flag set, then it was already
1139-
* handled through this path and this is a submission from the zone
1140-
* plug bio submit work.
1141-
*/
1142-
if (bio_flagged(bio, BIO_ZONE_WRITE_PLUGGING))
1143-
return false;
1144-
1145-
/*
1146-
* We do not need to do anything special for empty flush BIOs, e.g
1147-
* BIOs such as issued by blkdev_issue_flush(). The is because it is
1148-
* the responsibility of the user to first wait for the completion of
1149-
* write operations for flush to have any effect on the persistence of
1150-
* the written data.
1151-
*/
1152-
if (op_is_flush(bio->bi_opf) && !bio_sectors(bio))
1134+
if (WARN_ON_ONCE(!bdev->bd_disk->zone_wplugs_hash))
11531135
return false;
11541136

11551137
/*

drivers/md/dm.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1800,7 +1800,9 @@ static inline bool dm_zone_bio_needs_split(struct mapped_device *md,
18001800
}
18011801
static inline bool dm_zone_plug_bio(struct mapped_device *md, struct bio *bio)
18021802
{
1803-
return dm_emulate_zone_append(md) && blk_zone_plug_bio(bio, 0);
1803+
if (!bio_needs_zone_write_plugging(bio))
1804+
return false;
1805+
return blk_zone_plug_bio(bio, 0);
18041806
}
18051807

18061808
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
@@ -682,12 +682,67 @@ static inline unsigned int disk_nr_zones(struct gendisk *disk)
682682
{
683683
return disk->nr_zones;
684684
}
685+
686+
/**
687+
* bio_needs_zone_write_plugging - Check if a BIO needs to be handled with zone
688+
* write plugging
689+
* @bio: The BIO being submitted
690+
*
691+
* Return true whenever @bio execution needs to be handled through zone
692+
* write plugging (using blk_zone_plug_bio()). Return false otherwise.
693+
*/
694+
static inline bool bio_needs_zone_write_plugging(struct bio *bio)
695+
{
696+
enum req_op op = bio_op(bio);
697+
698+
/*
699+
* Only zoned block devices have a zone write plug hash table. But not
700+
* all of them have one (e.g. DM devices may not need one).
701+
*/
702+
if (!bio->bi_bdev->bd_disk->zone_wplugs_hash)
703+
return false;
704+
705+
/* Only write operations need zone write plugging. */
706+
if (!op_is_write(op))
707+
return false;
708+
709+
/* Ignore empty flush */
710+
if (op_is_flush(bio->bi_opf) && !bio_sectors(bio))
711+
return false;
712+
713+
/* Ignore BIOs that already have been handled by zone write plugging. */
714+
if (bio_flagged(bio, BIO_ZONE_WRITE_PLUGGING))
715+
return false;
716+
717+
/*
718+
* All zone write operations must be handled through zone write plugging
719+
* using blk_zone_plug_bio().
720+
*/
721+
switch (op) {
722+
case REQ_OP_ZONE_APPEND:
723+
case REQ_OP_WRITE:
724+
case REQ_OP_WRITE_ZEROES:
725+
case REQ_OP_ZONE_FINISH:
726+
case REQ_OP_ZONE_RESET:
727+
case REQ_OP_ZONE_RESET_ALL:
728+
return true;
729+
default:
730+
return false;
731+
}
732+
}
733+
685734
bool blk_zone_plug_bio(struct bio *bio, unsigned int nr_segs);
686735
#else /* CONFIG_BLK_DEV_ZONED */
687736
static inline unsigned int disk_nr_zones(struct gendisk *disk)
688737
{
689738
return 0;
690739
}
740+
741+
static inline bool bio_needs_zone_write_plugging(struct bio *bio)
742+
{
743+
return false;
744+
}
745+
691746
static inline bool blk_zone_plug_bio(struct bio *bio, unsigned int nr_segs)
692747
{
693748
return false;

0 commit comments

Comments
 (0)