]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
xfs: remove metafile inodes from the active inode stat
authorChristoph Hellwig <hch@lst.de>
Mon, 2 Feb 2026 14:14:32 +0000 (15:14 +0100)
committerCarlos Maiolino <cem@kernel.org>
Wed, 25 Feb 2026 12:58:48 +0000 (13:58 +0100)
The active inode (or active vnode until recently) stat can get much larger
than expected on file systems with a lot of metafile inodes like zoned
file systems on SMR hard disks with 10.000s of rtg rmap inodes.

Remove all metafile inodes from the active counter to make it more useful
to track actual workloads and add a separate counter for active metafile
inodes.

This fixes xfs/177 on SMR hard drives.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
fs/xfs/libxfs/xfs_inode_buf.c
fs/xfs/libxfs/xfs_metafile.c
fs/xfs/xfs_icache.c
fs/xfs/xfs_stats.c
fs/xfs/xfs_stats.h

index a017016e9075010fd64e8320c71c2e077a7102d8..3794e5412eba9a5e75f127d05306529825848dc0 100644 (file)
@@ -268,6 +268,10 @@ xfs_inode_from_disk(
        }
        if (xfs_is_reflink_inode(ip))
                xfs_ifork_init_cow(ip);
+       if (xfs_is_metadir_inode(ip)) {
+               XFS_STATS_DEC(ip->i_mount, xs_inodes_active);
+               XFS_STATS_INC(ip->i_mount, xs_inodes_meta);
+       }
        return 0;
 
 out_destroy_data_fork:
index cf239f86221241b264663e8b9adedd24df0e4afa..71f004e9dc6451069f209253344258b78f156de2 100644 (file)
@@ -61,6 +61,9 @@ xfs_metafile_set_iflag(
        ip->i_diflags2 |= XFS_DIFLAG2_METADATA;
        ip->i_metatype = metafile_type;
        xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+
+       XFS_STATS_DEC(ip->i_mount, xs_inodes_active);
+       XFS_STATS_INC(ip->i_mount, xs_inodes_meta);
 }
 
 /* Clear the metadata directory inode flag. */
@@ -74,6 +77,8 @@ xfs_metafile_clear_iflag(
 
        ip->i_diflags2 &= ~XFS_DIFLAG2_METADATA;
        xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+       XFS_STATS_INC(ip->i_mount, xs_inodes_active);
+       XFS_STATS_DEC(ip->i_mount, xs_inodes_meta);
 }
 
 /*
index f76c6decdaa3f138274d3e61fb19a16131d714c0..f2d4294efd371522b0bc853fb9368489f09cada1 100644 (file)
@@ -172,7 +172,10 @@ __xfs_inode_free(
        /* asserts to verify all state is correct here */
        ASSERT(atomic_read(&ip->i_pincount) == 0);
        ASSERT(!ip->i_itemp || list_empty(&ip->i_itemp->ili_item.li_bio_list));
-       XFS_STATS_DEC(ip->i_mount, xs_inodes_active);
+       if (xfs_is_metadir_inode(ip))
+               XFS_STATS_DEC(ip->i_mount, xs_inodes_meta);
+       else
+               XFS_STATS_DEC(ip->i_mount, xs_inodes_active);
 
        call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback);
 }
index bc4a5d6dc7951ea2080fea892daeed40353c7d7e..c13d600732c9560df6a3d54b600556b59d358f5f 100644 (file)
@@ -59,7 +59,8 @@ int xfs_stats_format(struct xfsstats __percpu *stats, char *buf)
                { "rtrefcntbt",         xfsstats_offset(xs_qm_dqreclaims)},
                /* we print both series of quota information together */
                { "qm",                 xfsstats_offset(xs_gc_read_calls)},
-               { "zoned",              xfsstats_offset(__pad1)},
+               { "zoned",              xfsstats_offset(xs_inodes_meta)},
+               { "metafile",           xfsstats_offset(xs_xstrat_bytes)},
        };
 
        /* Loop over all stats groups */
@@ -99,16 +100,20 @@ int xfs_stats_format(struct xfsstats __percpu *stats, char *buf)
 
 void xfs_stats_clearall(struct xfsstats __percpu *stats)
 {
+       uint32_t        xs_inodes_active, xs_inodes_meta;
        int             c;
-       uint32_t        xs_inodes_active;
 
        xfs_notice(NULL, "Clearing xfsstats");
        for_each_possible_cpu(c) {
                preempt_disable();
-               /* save xs_inodes_active, it's a universal truth! */
+               /*
+                * Save the active / meta inode counters, as they are stateful.
+                */
                xs_inodes_active = per_cpu_ptr(stats, c)->s.xs_inodes_active;
+               xs_inodes_meta = per_cpu_ptr(stats, c)->s.xs_inodes_meta;
                memset(per_cpu_ptr(stats, c), 0, sizeof(*stats));
                per_cpu_ptr(stats, c)->s.xs_inodes_active = xs_inodes_active;
+               per_cpu_ptr(stats, c)->s.xs_inodes_meta = xs_inodes_meta;
                preempt_enable();
        }
 }
index 64bc0cc181267524fdfa9260abbc15b7d708037a..57c32b86c358d2da33afb42909a51e6c7c87ae6f 100644 (file)
@@ -142,7 +142,8 @@ struct __xfsstats {
        uint32_t                xs_gc_read_calls;
        uint32_t                xs_gc_write_calls;
        uint32_t                xs_gc_zone_reset_calls;
-       uint32_t                __pad1;
+/* Metafile counters */
+       uint32_t                xs_inodes_meta;
 /* Extra precision counters */
        uint64_t                xs_xstrat_bytes;
        uint64_t                xs_write_bytes;