summaryrefslogtreecommitdiff
path: root/drivers/md
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2026-09-30 21:39:44 +0200
committerMikulas Patocka <mpatocka@redhat.com>2026-10-01 13:07:00 +0200
commitc1ab80af0d99a906b60b769f2e692c37d2db1323 (patch)
treee2be5ec8eae5637b9bc5d31cb782a6c9037326fd /drivers/md
parent78a6afc2999d26e5a30a56db77db34c22b88f5d5 (diff)
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 <mpatocka@redhat.com> 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")
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-writecache.c3
1 files changed, 2 insertions, 1 deletions
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;