xfs: remove metafile inodes from the active inode stat

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>
This commit is contained in:
Christoph Hellwig
2026-02-25 13:58:48 +01:00
committed by Carlos Maiolino
parent 03a6d6c4c8
commit 47553dd60b
5 changed files with 23 additions and 5 deletions
+4
View 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:
+5
View 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);
}
/*
+4 -1
View 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);
}
+8 -3
View 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();
}
}
+2 -1
View 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;