From c1ab80af0d99a906b60b769f2e692c37d2db1323 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Wed, 30 Sep 2026 21:39:44 +0200 Subject: dm-writecache: fix a quirk in statistics writecache_bio_copy_ssd() unconditionally adds the number of extra blocks in the merged bio to stats.writes_allocate. That is only correct when the entries were taken off the freelist. When the function is called with search_used == true -- i.e. from the write_hits_uncommitted / write_hits_committed paths in writecache_map_write() -- the first entry was found in the rbtree and every following entry is picked up with rb_next(), so nothing is allocated at all. Accordingly the writes_allocate++ that accompanies a successful writecache_pop_from_freelist() is skipped for that case, but the batch accounting below still adds n - 1. An in-place overwrite of n contiguous cached blocks therefore reports n - 1 allocations that never happened. Only the dmsetup status output is affected; there is no functional change. Signed-off-by: Mikulas Patocka Assisted-by: Claude:claude-opus-5 Cc: stable@vger.kernel.org Fixes: b2676e1482af ("dm writecache: count number of blocks written, not number of write bios") --- drivers/md/dm-writecache.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/md') diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c index e278359cb268..e974204b0d6f 100644 --- a/drivers/md/dm-writecache.c +++ b/drivers/md/dm-writecache.c @@ -1425,7 +1425,8 @@ static void writecache_bio_copy_ssd(struct dm_writecache *wc, struct bio *bio, dm_accept_partial_bio(bio, bio_size >> SECTOR_SHIFT); wc->stats.writes += bio->bi_iter.bi_size >> wc->block_size_bits; - wc->stats.writes_allocate += (bio->bi_iter.bi_size - wc->block_size) >> wc->block_size_bits; + if (!search_used) + wc->stats.writes_allocate += (bio->bi_iter.bi_size - wc->block_size) >> wc->block_size_bits; if (unlikely(wc->uncommitted_blocks >= wc->autocommit_blocks)) { wc->uncommitted_blocks = 0; -- cgit v1.2.3