diff options
author | Darrick J. Wong <djwong@kernel.org> | 2022-07-14 11:15:07 -0700 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2022-10-14 14:17:00 -0700 |
commit | 5fee5ae19148da59637e26b717d00ab2571d1c73 (patch) | |
tree | 739a704a14e887a4d4f21ce8816428f209c3e9c2 | |
parent | cc801d90e28fca15c3f3be6ef705c3a894699531 (diff) |
xfs: refactor the v4 group/project inode pointer switch
Refactor the group and project quota inode pointer switcheroo that
happens only on v4 filesystems into a separate function prior to
enhancing the xfs_qm_qino_alloc function.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
-rw-r--r-- | fs/xfs/xfs_qm.c | 92 |
1 files changed, 55 insertions, 37 deletions
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 78d1dd6a8b8f..8e15a2c0f6a1 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -724,6 +724,57 @@ xfs_qm_destroy_quotainfo( } /* + * Switch the group and project quota in-core inode pointers if needed. + * + * On v4 superblocks that don't have separate pquotino, we share an inode + * between gquota and pquota. If the on-disk superblock has GQUOTA and the + * filesystem is now mounted with PQUOTA, just use sb_gquotino for sb_pquotino + * and vice-versa. + */ +STATIC int +xfs_qm_qino_switch( + struct xfs_mount *mp, + struct xfs_inode **ipp, + unsigned int flags, + bool *need_alloc) +{ + xfs_ino_t ino = NULLFSINO; + int error; + + if (xfs_has_pquotino(mp) || + !(flags & (XFS_QMOPT_PQUOTA | XFS_QMOPT_GQUOTA))) + return 0; + + if ((flags & XFS_QMOPT_PQUOTA) && + (mp->m_sb.sb_gquotino != NULLFSINO)) { + ino = mp->m_sb.sb_gquotino; + if (XFS_IS_CORRUPT(mp, mp->m_sb.sb_pquotino != NULLFSINO)) { + xfs_fs_mark_sick(mp, XFS_SICK_FS_PQUOTA); + return -EFSCORRUPTED; + } + } else if ((flags & XFS_QMOPT_GQUOTA) && + (mp->m_sb.sb_pquotino != NULLFSINO)) { + ino = mp->m_sb.sb_pquotino; + if (XFS_IS_CORRUPT(mp, mp->m_sb.sb_gquotino != NULLFSINO)) { + xfs_fs_mark_sick(mp, XFS_SICK_FS_GQUOTA); + return -EFSCORRUPTED; + } + } + + if (ino == NULLFSINO) + return 0; + + error = xfs_iget(mp, NULL, ino, 0, 0, ipp); + if (error) + return error; + + mp->m_sb.sb_gquotino = NULLFSINO; + mp->m_sb.sb_pquotino = NULLFSINO; + *need_alloc = false; + return 0; +} + +/* * Create an inode and return with a reference already taken, but unlocked * This is how we create quota inodes */ @@ -738,43 +789,10 @@ xfs_qm_qino_alloc( bool need_alloc = true; *ipp = NULL; - /* - * With superblock that doesn't have separate pquotino, we - * share an inode between gquota and pquota. If the on-disk - * superblock has GQUOTA and the filesystem is now mounted - * with PQUOTA, just use sb_gquotino for sb_pquotino and - * vice-versa. - */ - if (!xfs_has_pquotino(mp) && - (flags & (XFS_QMOPT_PQUOTA|XFS_QMOPT_GQUOTA))) { - xfs_ino_t ino = NULLFSINO; - - if ((flags & XFS_QMOPT_PQUOTA) && - (mp->m_sb.sb_gquotino != NULLFSINO)) { - ino = mp->m_sb.sb_gquotino; - if (XFS_IS_CORRUPT(mp, - mp->m_sb.sb_pquotino != NULLFSINO)) { - xfs_fs_mark_sick(mp, XFS_SICK_FS_PQUOTA); - return -EFSCORRUPTED; - } - } else if ((flags & XFS_QMOPT_GQUOTA) && - (mp->m_sb.sb_pquotino != NULLFSINO)) { - ino = mp->m_sb.sb_pquotino; - if (XFS_IS_CORRUPT(mp, - mp->m_sb.sb_gquotino != NULLFSINO)) { - xfs_fs_mark_sick(mp, XFS_SICK_FS_GQUOTA); - return -EFSCORRUPTED; - } - } - if (ino != NULLFSINO) { - error = xfs_iget(mp, NULL, ino, 0, 0, ipp); - if (error) - return error; - mp->m_sb.sb_gquotino = NULLFSINO; - mp->m_sb.sb_pquotino = NULLFSINO; - need_alloc = false; - } - } + + error = xfs_qm_qino_switch(mp, ipp, flags, &need_alloc); + if (error) + return error; error = xfs_trans_alloc(mp, &M_RES(mp)->tr_create, need_alloc ? XFS_QM_QINOCREATE_SPACE_RES(mp) : 0, |