From: Darrick J. Wong <djwong@xxxxxxxxxx> 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@xxxxxxxxxx> --- fs/xfs/xfs_qm.c | 90 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 36 deletions(-) diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 07d0d0231252a..3e7e0f9cecc0e 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -732,6 +732,57 @@ xfs_qm_destroy_quotainfo( mp->m_quotainfo = NULL; } +/* + * 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 @@ -747,43 +798,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,