summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2020-10-25 17:16:01 -0700
committerDarrick J. Wong <darrick.wong@oracle.com>2020-10-26 18:32:29 -0700
commit2ad07443587573243f76f4cb6446c9a6a4b01e13 (patch)
tree72936d4dfc0d1f9323b1e74d5d81d364c1933086 /fs
parent338ccdf0dbc85791bf951652ed912c6fdb8228cb (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.c91
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,