]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: generalize the freespace and reserved blocks handling
authorChristoph Hellwig <hch@lst.de>
Mon, 14 Apr 2025 05:35:44 +0000 (07:35 +0200)
committerAndrey Albershteyn <aalbersh@kernel.org>
Tue, 29 Apr 2025 16:09:57 +0000 (18:09 +0200)
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@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christoph Hellwig <hch@lst.de>
include/xfs_mount.h
libxfs/libxfs_priv.h
libxfs/xfs_ialloc.c
libxfs/xfs_metafile.c
libxfs/xfs_sb.c
libxfs/xfs_types.h

index 383cba7d6e3fee676aefb1b9bdcf674f87c1cf14..e0f72fc32b251691a237819530218b9eb6e130c9 100644 (file)
@@ -63,8 +63,6 @@ typedef struct xfs_mount {
        xfs_sb_t                m_sb;           /* copy of fs superblock */
 #define m_icount       m_sb.sb_icount
 #define m_ifree                m_sb.sb_ifree
-#define m_fdblocks     m_sb.sb_fdblocks
-#define m_frextents    m_sb.sb_frextents
        spinlock_t              m_sb_lock;
 
        /*
@@ -332,6 +330,36 @@ static inline bool xfs_is_ ## name (struct xfs_mount *mp) \
 __XFS_UNSUPP_OPSTATE(readonly)
 __XFS_UNSUPP_OPSTATE(shutdown)
 
+static inline int64_t xfs_sum_freecounter(struct xfs_mount *mp,
+               enum xfs_free_counter ctr)
+{
+       if (ctr == XC_FREE_RTEXTENTS)
+               return mp->m_sb.sb_frextents;
+       return mp->m_sb.sb_fdblocks;
+}
+
+static inline int64_t xfs_estimate_freecounter(struct xfs_mount *mp,
+               enum xfs_free_counter ctr)
+{
+       return xfs_sum_freecounter(mp, ctr);
+}
+
+static inline int xfs_compare_freecounter(struct xfs_mount *mp,
+               enum xfs_free_counter ctr, int64_t rhs, int32_t batch)
+{
+       uint64_t count;
+
+       if (ctr == XC_FREE_RTEXTENTS)
+               count = mp->m_sb.sb_frextents;
+       else
+               count = mp->m_sb.sb_fdblocks;
+       if (count > rhs)
+               return 1;
+       else if (count < rhs)
+               return -1;
+       return 0;
+}
+
 /* don't fail on device size or AG count checks */
 #define LIBXFS_MOUNT_DEBUGGER          (1U << 0)
 /* report metadata corruption to stdout */
index 7e5c125b581a2f38db6d426b9acab3fc897bceab..cb4800de0b1100b006ffb6cf7e9dee7416cd2a0c 100644 (file)
@@ -209,7 +209,7 @@ static inline bool WARN_ON(bool expr) {
 }
 
 #define WARN_ON_ONCE(e)                        WARN_ON(e)
-#define percpu_counter_read(x)         (*x)
+
 #define percpu_counter_read_positive(x)        ((*x) > 0 ? (*x) : 0)
 #define percpu_counter_sum_positive(x) ((*x) > 0 ? (*x) : 0)
 
@@ -219,17 +219,6 @@ uint32_t get_random_u32(void);
 #define get_random_u32()       (0)
 #endif
 
-static inline int
-__percpu_counter_compare(uint64_t *count, int64_t rhs, int32_t batch)
-{
-       if (*count > rhs)
-               return 1;
-       else if (*count < rhs)
-               return -1;
-       return 0;
-}
-
-
 #define PAGE_SIZE              getpagesize()
 extern unsigned int PAGE_SHIFT;
 
index 63ce76755eb77f55b3e2e7ae6334e4d0ae2d82ce..b401299ad933f76b7bbfbeba881ef88428d93982 100644 (file)
@@ -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;
index 4488e38a87345a23806247718bf6726fb9e452f7..7673265510fdf77db6f9d48397fd421a3c7c4e18 100644 (file)
@@ -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;
 }
 
index 50a43c0328cb93c350979e9a71fcec39bdca2c29..1781ca36b2cce44176cf9b579fb60eb7a22f56d4 100644 (file)
@@ -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);
index ca2401c1facda7e164e590158b8290f248a35f13..76f3c31573ec378d513229f518972cfce5e19ee9 100644 (file)
@@ -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
  */