diff mbox series

[11/21] xfs: refactor special inode roll out of xfs_dir_ialloc

Message ID 157784122440.1365473.15001800973344418611.stgit@magnolia (mailing list archive)
State Deferred, archived
Headers show
Series xfs: hoist inode operations to libxfs | expand

Commit Message

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

In xfs_dir_ialloc, we roll the transaction if we had to allocate a new
inode chunk and before we actually initialize the inode.  In the kernel
this requires us to detach the transaction's quota charge information
from the ichunk allocation transaction and to attach it the ialloc
transaction because we don't charge quota for inode chunks.  This
doesn't exist in the userspace side of things, so pop it out into a
separately called function.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_inode_util.h |    1 +
 fs/xfs/xfs_inode.c             |   65 ++++++++++++++++++++++++----------------
 2 files changed, 40 insertions(+), 26 deletions(-)
diff mbox series

Patch

diff --git a/fs/xfs/libxfs/xfs_inode_util.h b/fs/xfs/libxfs/xfs_inode_util.h
index b54495182932..2ee6e5bfb80a 100644
--- a/fs/xfs/libxfs/xfs_inode_util.h
+++ b/fs/xfs/libxfs/xfs_inode_util.h
@@ -39,6 +39,7 @@  void xfs_setup_inode(struct xfs_inode *ip);
 void xfs_trans_ichgtime(struct xfs_trans *tp, struct xfs_inode *ip, int flags);
 int xfs_ialloc_iget(struct xfs_trans *tp, xfs_ino_t ino,
 		    struct xfs_inode **ipp);
+int xfs_dir_ialloc_roll(struct xfs_trans **tpp);
 
 int xfs_ialloc(struct xfs_trans *tp, const struct xfs_ialloc_args *args,
 	       struct xfs_buf **ialloc_context, struct xfs_inode **ipp);
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index eef85fbb6102..0d1cfc85a268 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -632,6 +632,44 @@  xfs_ialloc_iget(
 			ipp);
 }
 
+/*
+ * Roll the transaction after allocating an inode chunk and before allocating
+ * the actual inode, moving the quota charge information to the second
+ * transaction.
+ */
+int
+xfs_dir_ialloc_roll(
+	struct xfs_trans	**tpp)
+{
+	struct xfs_dquot_acct	*dqinfo = NULL;
+	unsigned int		tflags = 0;
+	int			error;
+
+	/*
+	 * We want the quota changes to be associated with the next
+	 * transaction, NOT this one. So, detach the dqinfo from this
+	 * and attach it to the next transaction.
+	 */
+	if ((*tpp)->t_dqinfo) {
+		dqinfo = (*tpp)->t_dqinfo;
+		(*tpp)->t_dqinfo = NULL;
+		tflags = (*tpp)->t_flags & XFS_TRANS_DQ_DIRTY;
+		(*tpp)->t_flags &= ~(XFS_TRANS_DQ_DIRTY);
+	}
+
+	error = xfs_trans_roll(tpp);
+
+	/*
+	 * Re-attach the quota info that we detached from prev trx.
+	 */
+	if (dqinfo) {
+		(*tpp)->t_dqinfo = dqinfo;
+		(*tpp)->t_flags |= tflags;
+	}
+
+	return error;
+}
+
 /*
  * Allocates a new inode from disk and return a pointer to the
  * incore copy. This routine will internally commit the current
@@ -651,8 +689,6 @@  xfs_dir_ialloc(
 	struct xfs_trans		*tp;
 	struct xfs_inode		*ip;
 	struct xfs_buf			*ialloc_context = NULL;
-	void				*dqinfo;
-	uint				tflags;
 	int				code;
 
 	tp = *tpp;
@@ -705,30 +741,7 @@  xfs_dir_ialloc(
 		 */
 		xfs_trans_bhold(tp, ialloc_context);
 
-		/*
-		 * We want the quota changes to be associated with the next
-		 * transaction, NOT this one. So, detach the dqinfo from this
-		 * and attach it to the next transaction.
-		 */
-		dqinfo = NULL;
-		tflags = 0;
-		if (tp->t_dqinfo) {
-			dqinfo = (void *)tp->t_dqinfo;
-			tp->t_dqinfo = NULL;
-			tflags = tp->t_flags & XFS_TRANS_DQ_DIRTY;
-			tp->t_flags &= ~(XFS_TRANS_DQ_DIRTY);
-		}
-
-		code = xfs_trans_roll(&tp);
-
-		/*
-		 * Re-attach the quota info that we detached from prev trx.
-		 */
-		if (dqinfo) {
-			tp->t_dqinfo = dqinfo;
-			tp->t_flags |= tflags;
-		}
-
+		code = xfs_dir_ialloc_roll(&tp);
 		if (code) {
 			xfs_buf_relse(ialloc_context);
 			*tpp = tp;