]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: disable the agi rotor for metadata inodes
authorDarrick J. Wong <djwong@kernel.org>
Mon, 25 Nov 2024 21:14:17 +0000 (13:14 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 24 Dec 2024 02:01:25 +0000 (18:01 -0800)
Source kernel commit: 8651b410ae781cc607159c51dbb0b317b23543b1

Ideally, we'd put all the metadata inodes in one place if we could, so
that the metadata all stay reasonably close together instead of
spreading out over the disk.  Furthermore, if the log is internal we'd
probably prefer to keep the metadata near the log.  Therefore, disable
AGI rotoring for metadata inode allocations.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
libxfs/xfs_ialloc.c

index 055eff477facebbc040ee3729256b985203b3f3d..2575447f92dfbb6ce00ef8e989215e494127105e 100644 (file)
@@ -1836,6 +1836,40 @@ out_release:
        return error;
 }
 
+/*
+ * Pick an AG for the new inode.
+ *
+ * Directories, symlinks, and regular files frequently allocate at least one
+ * block, so factor that potential expansion when we examine whether an AG has
+ * enough space for file creation.  Try to keep metadata files all in the same
+ * AG.
+ */
+static inline xfs_agnumber_t
+xfs_dialloc_pick_ag(
+       struct xfs_mount        *mp,
+       struct xfs_inode        *dp,
+       umode_t                 mode)
+{
+       xfs_agnumber_t          start_agno;
+
+       if (!dp)
+               return 0;
+       if (xfs_is_metadir_inode(dp)) {
+               if (mp->m_sb.sb_logstart)
+                       return XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart);
+               return 0;
+       }
+
+       if (S_ISDIR(mode))
+               return (atomic_inc_return(&mp->m_agirotor) - 1) % mp->m_maxagi;
+
+       start_agno = XFS_INO_TO_AGNO(mp, dp->i_ino);
+       if (start_agno >= mp->m_maxagi)
+               start_agno = 0;
+
+       return start_agno;
+}
+
 /*
  * Allocate an on-disk inode.
  *
@@ -1851,31 +1885,19 @@ xfs_dialloc(
        xfs_ino_t               *new_ino)
 {
        struct xfs_mount        *mp = (*tpp)->t_mountp;
+       struct xfs_perag        *pag;
+       struct xfs_ino_geometry *igeo = M_IGEO(mp);
+       xfs_ino_t               ino = NULLFSINO;
        xfs_ino_t               parent = args->pip ? args->pip->i_ino : 0;
-       umode_t                 mode = args->mode & S_IFMT;
        xfs_agnumber_t          agno;
-       int                     error = 0;
        xfs_agnumber_t          start_agno;
-       struct xfs_perag        *pag;
-       struct xfs_ino_geometry *igeo = M_IGEO(mp);
+       umode_t                 mode = args->mode & S_IFMT;
        bool                    ok_alloc = true;
        bool                    low_space = false;
        int                     flags;
-       xfs_ino_t               ino = NULLFSINO;
+       int                     error = 0;
 
-       /*
-        * Directories, symlinks, and regular files frequently allocate at least
-        * one block, so factor that potential expansion when we examine whether
-        * an AG has enough space for file creation.
-        */
-       if (S_ISDIR(mode))
-               start_agno = (atomic_inc_return(&mp->m_agirotor) - 1) %
-                               mp->m_maxagi;
-       else {
-               start_agno = XFS_INO_TO_AGNO(mp, parent);
-               if (start_agno >= mp->m_maxagi)
-                       start_agno = 0;
-       }
+       start_agno = xfs_dialloc_pick_ag(mp, args->pip, mode);
 
        /*
         * If we have already hit the ceiling of inode blocks then clear