diff mbox series

[04/13] xfs: convert all users to xfs_imeta_log

Message ID 157784131602.1366873.16394167814770541277.stgit@magnolia (mailing list archive)
State Superseded, archived
Headers show
Series xfs: metadata inode directories | expand

Commit Message

Darrick J. Wong Jan. 1, 2020, 1:15 a.m. UTC
From: Darrick J. Wong <darrick.wong@oracle.com>

Convert all open-coded sb metadata inode pointer logging to use
xfs_imeta_log.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_qm.c |   77 ++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 48 insertions(+), 29 deletions(-)
diff mbox series

Patch

diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 66966178244d..2502312ee504 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -24,6 +24,7 @@ 
 #include "xfs_icache.h"
 #include "xfs_error.h"
 #include "xfs_health.h"
+#include "xfs_imeta.h"
 
 /*
  * The global quota manager. There is only one of these for the entire
@@ -747,6 +748,18 @@  xfs_qm_destroy_quotainfo(
 	mp->m_quotainfo = NULL;
 }
 
+static inline const struct xfs_imeta_path *
+xfs_qflags_to_imeta(
+	unsigned int	qflags)
+{
+	if (qflags & XFS_QMOPT_UQUOTA)
+		return &XFS_IMETA_USRQUOTA;
+	else if (qflags & XFS_QMOPT_GQUOTA)
+		return &XFS_IMETA_GRPQUOTA;
+	else
+		return &XFS_IMETA_PRJQUOTA;
+}
+
 /*
  * Switch the group and project quota in-core inode pointers if needed.
  *
@@ -754,6 +767,12 @@  xfs_qm_destroy_quotainfo(
  * 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.
+ *
+ * We tolerate the direct manipulation of the in-core sb quota inode pointers
+ * here because calling xfs_imeta_log is only really required for filesystems
+ * with the metadata directory feature.  That feature requires a v5 superblock,
+ * which always supports simultaneous group and project quotas, so we'll never
+ * get here.
  */
 STATIC int
 xfs_qm_qino_switch(
@@ -792,8 +811,13 @@  xfs_qm_qino_switch(
 	if (error)
 		return error;
 
-	mp->m_sb.sb_gquotino = NULLFSINO;
-	mp->m_sb.sb_pquotino = NULLFSINO;
+	if (flags & XFS_QMOPT_PQUOTA) {
+		mp->m_sb.sb_gquotino = NULLFSINO;
+		mp->m_sb.sb_pquotino = ino;
+	} else if (flags & XFS_QMOPT_GQUOTA) {
+		mp->m_sb.sb_gquotino = ino;
+		mp->m_sb.sb_pquotino = NULLFSINO;
+	}
 	*need_alloc = false;
 	return 0;
 }
@@ -804,36 +828,26 @@  xfs_qm_qino_switch(
  */
 STATIC int
 xfs_qm_qino_alloc(
-	xfs_mount_t	*mp,
-	xfs_inode_t	**ip,
-	uint		flags)
+	struct xfs_mount		*mp,
+	struct xfs_inode		**ip,
+	uint				flags)
 {
-	struct xfs_ialloc_args	args = {
-		.nlink	= 1,
-		.mode	= S_IFREG,
-	};
-	xfs_trans_t	*tp;
-	int		error;
-	bool		need_alloc = true;
+	struct xfs_imeta_end		ic;
+	struct xfs_trans		*tp;
+	const struct xfs_imeta_path	*path = xfs_qflags_to_imeta(flags);
+	int				error;
+	bool				need_alloc = true;
 
 	*ip = NULL;
 	error = xfs_qm_qino_switch(mp, ip, flags, &need_alloc);
 	if (error)
 		return error;
 
-	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_create,
-			XFS_QM_QINOCREATE_SPACE_RES(mp), 0, 0, &tp);
+	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_imeta_create,
+			xfs_imeta_create_space_res(mp), 0, 0, &tp);
 	if (error)
 		return error;
 
-	if (need_alloc) {
-		error = xfs_dir_ialloc(&tp, &args, ip);
-		if (error) {
-			xfs_trans_cancel(tp);
-			return error;
-		}
-	}
-
 	/*
 	 * Make the changes in the superblock, and log those too.
 	 * sbfields arg may contain fields other than *QUOTINO;
@@ -851,22 +865,27 @@  xfs_qm_qino_alloc(
 		/* qflags will get updated fully _after_ quotacheck */
 		mp->m_sb.sb_qflags = mp->m_qflags & XFS_ALL_QUOTA_ACCT;
 	}
-	if (flags & XFS_QMOPT_UQUOTA)
-		mp->m_sb.sb_uquotino = (*ip)->i_ino;
-	else if (flags & XFS_QMOPT_GQUOTA)
-		mp->m_sb.sb_gquotino = (*ip)->i_ino;
-	else
-		mp->m_sb.sb_pquotino = (*ip)->i_ino;
 	spin_unlock(&mp->m_sb_lock);
 	xfs_log_sb(tp);
 
+	if (need_alloc) {
+		error = xfs_imeta_create(&tp, path, S_IFREG, ip, &ic);
+		if (error) {
+			xfs_trans_cancel(tp);
+			xfs_imeta_end_update(mp, &ic, error);
+			return error;
+		}
+	}
+
 	error = xfs_trans_commit(tp);
 	if (error) {
 		ASSERT(XFS_FORCED_SHUTDOWN(mp));
 		xfs_alert(mp, "%s failed (error %d)!", __func__, error);
 	}
-	if (need_alloc)
+	if (need_alloc) {
+		xfs_imeta_end_update(mp, &ic, error);
 		xfs_finish_inode_setup(*ip);
+	}
 	return error;
 }