@@ -82,6 +82,12 @@ struct xfs_ialloc_ops {
/* Do any final setup needed before we return the inode. */
void (*setup)(struct xfs_inode *ip);
+
+ /*
+ * Roll the transaction between allocating a new ichunk and
+ * initializing a new inode core.
+ */
+ int (*ichunk_roll)(struct xfs_trans **tpp);
};
/* The libxfs client must provide this symbol. */
@@ -647,10 +647,49 @@ xfs_ialloc_platform_init(
VFS_I(ip)->i_ctime = tv;
}
+/*
+ * Roll the transaction after allocating an inode chunk and before allocating
+ * the actual inode, moving the quota charge information to the second
+ * transaction.
+ */
+static 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;
+}
+
const struct xfs_ialloc_ops xfs_default_ialloc_ops = {
.iget = xfs_ialloc_iget,
.platform_init = xfs_ialloc_platform_init,
.setup = xfs_setup_inode,
+ .ichunk_roll = xfs_dir_ialloc_roll,
};
/*
@@ -672,8 +711,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;
@@ -726,30 +763,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 = args->ops->ichunk_roll(&tp);
if (code) {
xfs_buf_relse(ialloc_context);
*tpp = tp;