diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2020-10-25 17:16:01 -0700 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2020-10-26 18:32:29 -0700 |
commit | 2ad07443587573243f76f4cb6446c9a6a4b01e13 (patch) | |
tree | 72936d4dfc0d1f9323b1e74d5d81d364c1933086 /fs | |
parent | 338ccdf0dbc85791bf951652ed912c6fdb8228cb (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 <darrick.wong@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/xfs_qm.c | 91 |
1 files changed, 54 insertions, 37 deletions
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index e065e3bbba01..d2a14b75a8d1 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -751,6 +751,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 **ip, + unsigned int flags, + bool *need_alloc) +{ + xfs_ino_t ino = NULLFSINO; + int error; + + if (xfs_sb_version_has_pquotino(&mp->m_sb) || + !(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, ip); + 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 */ @@ -769,43 +820,9 @@ xfs_qm_qino_alloc( bool need_alloc = true; *ip = 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_sb_version_has_pquotino(&mp->m_sb) && - (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, ip); - 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, ip, 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, |