xfs: disable the agi rotor for metadata inodes

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>
This commit is contained in:
Darrick J. Wong 2024-11-03 20:18:52 -08:00
parent 5d9b54a4ef
commit 8651b410ae

View File

@ -1841,6 +1841,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.
*
@ -1856,31 +1890,19 @@ xfs_dialloc(
xfs_ino_t *new_ino)
{
struct xfs_mount *mp = (*tpp)->t_mountp;
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);
xfs_ino_t ino = NULLFSINO;
xfs_ino_t parent = args->pip ? args->pip->i_ino : 0;
xfs_agnumber_t agno;
xfs_agnumber_t start_agno;
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