From: Qu Wenruo Date: Tue, 7 Apr 2026 09:34:01 +0000 (+0930) Subject: btrfs: avoid unnecessary dev stats updates X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=5d40d064db81d8b4fad89079c916571f712cb1de;p=thirdparty%2Flinux.git btrfs: avoid unnecessary dev stats updates [MINOR PROBLEM] When mounting a filesystem with a valid DEV_STATS item, we will always update the DEV_STATS again in the next transaction commit, even if there is no change the values. [CAUSE] During the mount, btrfs_device_init_dev_stats() will read out the on-disk DEV_STATS item for each device. Then it calls btrfs_dev_stat_set() to update the in-memory structure. However btrfs_dev_stat_set() does not only set the dev stats value, but also increase device->dev_stats_ccnt. That member determines if we should update the device item at the next transaction commit. Since we have called btrfs_dev_stat_set() for each dev status member, dev_stats_ccnt will be non-zero and we will update the dev stats item even it doesn't change at all. [FIX] Instead of using btrfs_dev_stat_set() for valid on-disk DEV_STATUS values, directly call atomic_set() to set the in-memory values. For other call sites, we still want to use btrfs_dev_stat_set() so that we will force updating/creating the dev stats item. Signed-off-by: Qu Wenruo Signed-off-by: David Sterba --- diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 42615e6e79925..4cd9033320f76 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -8209,8 +8209,8 @@ static int btrfs_device_init_dev_stats(struct btrfs_device *device, for (i = 0; i < BTRFS_DEV_STAT_VALUES_MAX; i++) { if (item_size >= (1 + i) * sizeof(__le64)) - btrfs_dev_stat_set(device, i, - btrfs_dev_stats_value(eb, ptr, i)); + atomic_set(device->dev_stat_values + i, + btrfs_dev_stats_value(eb, ptr, i)); else btrfs_dev_stat_set(device, i, 0); }