[PATCH v3 03/21] md: skip bitmap accounting for empty write ranges
From: Yu Kuai <yukuai@kernel.org>
Date: 2026-07-28 08:49:44
Also in:
lkml
Subsystem:
software raid (multiple disks) support, the rest · Maintainers:
Song Liu, Yu Kuai, Linus Torvalds
From: Yu Kuai <yukuai@fygo.io> mkfs.ext4 can submit zero-sector flush/FUA bios. These bios are WRITE bios for md_write_start() purposes, but they do not cover any data sector and must not dirty bitmap bits. md bitmap accounting currently passes such bios to bitmap start_write(). For llbitmap this reaches llbitmap_start_write() with sectors == 0, which underflows the end chunk calculation. The new bitmap prepare_range() hook can also turn a non-empty bio into an empty bitmap range when the requested sectors are outside the active bitmap geometry. Treat both cases as not started, so the completion path will not call end_write() for an empty range. Signed-off-by: Yu Kuai <yukuai@fygo.io> --- drivers/md/md.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 3b20a57b8c7e..0b59c676f7c0 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c@@ -9376,6 +9376,8 @@ static void md_bitmap_start(struct mddev *mddev, md_bitmap_prepare_range(mddev, &md_io_clone->offset, &md_io_clone->sectors); + if (!md_io_clone->sectors) + return; fn(mddev, md_io_clone->offset, md_io_clone->sectors); }
@@ -9396,7 +9398,8 @@ static void md_end_clone_io(struct bio *bio) struct mddev *mddev = md_io_clone->mddev; struct completion *reshape_completion = bio->bi_private; - if (bio_data_dir(orig_bio) == WRITE && md_bitmap_enabled(mddev, false)) + if (bio_data_dir(orig_bio) == WRITE && md_io_clone->sectors && + md_bitmap_enabled(mddev, false)) md_bitmap_end(mddev, md_io_clone); if (bio->bi_status && !orig_bio->bi_status)
@@ -9423,10 +9426,12 @@ static void md_clone_bio(struct mddev *mddev, struct bio **bio) md_io_clone = container_of(clone, struct md_io_clone, bio_clone); md_io_clone->orig_bio = *bio; md_io_clone->mddev = mddev; + md_io_clone->sectors = 0; if (blk_queue_io_stat(bdev->bd_disk->queue)) md_io_clone->start_time = bio_start_io_acct(*bio); - if (bio_data_dir(*bio) == WRITE && md_bitmap_enabled(mddev, false)) { + if (bio_data_dir(*bio) == WRITE && bio_sectors(*bio) && + md_bitmap_enabled(mddev, false)) { md_io_clone->offset = (*bio)->bi_iter.bi_sector; md_io_clone->sectors = bio_sectors(*bio); md_io_clone->rw = op_stat_group(bio_op(*bio));
--
2.51.0