Source kernel commit: 712bae96631852c1a1822ee4f57a08ccd843358b xfs_{add,dec}_freecounter already handles the block and RT extent percpu counters, but it currently hardcodes the passed in counter. Add a freecounter abstraction that uses an enum to designate the counter and add wrappers that hide the actual percpu_counters. This will allow expanding the reserved block handling to the RT extent counter in the next step, and also prepares for adding yet another such counter that can share the code. Both these additions will be needed for the zoned allocator. Also switch the flooring of the frextents counter to 0 in statfs for the rthinherit case to a manual min_t call to match the handling of the fdblocks counter for normal file systems. Signed-off-by: Christoph Hellwig <hch@xxxxxx> Reviewed-by: "Darrick J. Wong" <djwong@xxxxxxxxxx> Signed-off-by: Christoph Hellwig <hch@xxxxxx> --- libxfs/xfs_ialloc.c | 2 +- libxfs/xfs_metafile.c | 2 +- libxfs/xfs_sb.c | 8 ++++---- libxfs/xfs_types.h | 17 +++++++++++++++++ 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c index 63ce76755eb7..b401299ad933 100644 --- a/libxfs/xfs_ialloc.c +++ b/libxfs/xfs_ialloc.c @@ -1922,7 +1922,7 @@ xfs_dialloc( * that we can immediately allocate, but then we allow allocation on the * second pass if we fail to find an AG with free inodes in it. */ - if (percpu_counter_read_positive(&mp->m_fdblocks) < + if (xfs_estimate_freecounter(mp, XC_FREE_BLOCKS) < mp->m_low_space[XFS_LOWSP_1_PCNT]) { ok_alloc = false; low_space = true; diff --git a/libxfs/xfs_metafile.c b/libxfs/xfs_metafile.c index 4488e38a8734..7673265510fd 100644 --- a/libxfs/xfs_metafile.c +++ b/libxfs/xfs_metafile.c @@ -93,7 +93,7 @@ xfs_metafile_resv_can_cover( * There aren't enough blocks left in the inode's reservation, but it * isn't critical unless there also isn't enough free space. */ - return __percpu_counter_compare(&ip->i_mount->m_fdblocks, + return xfs_compare_freecounter(ip->i_mount, XC_FREE_BLOCKS, rhs - ip->i_delayed_blks, 2048) >= 0; } diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c index 50a43c0328cb..1781ca36b2cc 100644 --- a/libxfs/xfs_sb.c +++ b/libxfs/xfs_sb.c @@ -1262,8 +1262,7 @@ xfs_log_sb( mp->m_sb.sb_ifree = min_t(uint64_t, percpu_counter_sum_positive(&mp->m_ifree), mp->m_sb.sb_icount); - mp->m_sb.sb_fdblocks = - percpu_counter_sum_positive(&mp->m_fdblocks); + mp->m_sb.sb_fdblocks = xfs_sum_freecounter(mp, XC_FREE_BLOCKS); } /* @@ -1272,9 +1271,10 @@ xfs_log_sb( * we handle nearly-lockless reservations, so we must use the _positive * variant here to avoid writing out nonsense frextents. */ - if (xfs_has_rtgroups(mp)) + if (xfs_has_rtgroups(mp)) { mp->m_sb.sb_frextents = - percpu_counter_sum_positive(&mp->m_frextents); + xfs_sum_freecounter(mp, XC_FREE_RTEXTENTS); + } xfs_sb_to_disk(bp->b_addr, &mp->m_sb); xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); diff --git a/libxfs/xfs_types.h b/libxfs/xfs_types.h index ca2401c1facd..76f3c31573ec 100644 --- a/libxfs/xfs_types.h +++ b/libxfs/xfs_types.h @@ -233,6 +233,23 @@ enum xfs_group_type { { XG_TYPE_AG, "ag" }, \ { XG_TYPE_RTG, "rtg" } +enum xfs_free_counter { + /* + * Number of free blocks on the data device. + */ + XC_FREE_BLOCKS, + + /* + * Number of free RT extents on the RT device. + */ + XC_FREE_RTEXTENTS, + XC_FREE_NR, +}; + +#define XFS_FREECOUNTER_STR \ + { XC_FREE_BLOCKS, "blocks" }, \ + { XC_FREE_RTEXTENTS, "rtextents" } + /* * Type verifier functions */ -- 2.47.2