]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: introduce xfs_dialloc_roll()
authorDave Chinner <dchinner@redhat.com>
Thu, 7 Jan 2021 20:59:17 +0000 (15:59 -0500)
committerEric Sandeen <sandeen@sandeen.net>
Thu, 7 Jan 2021 20:59:17 +0000 (15:59 -0500)
Source kernel commit: aececc9f8dec92a25c84a3378021636ce58d72dc

Introduce a helper to make the on-disk inode allocation rolling
logic clearer in preparation of the following cleanup.

[sandeen: update xfsprogs struct xfs_trans to match]

Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@redhat.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
include/xfs_trans.h
libxfs/util.c
libxfs/xfs_ialloc.c
libxfs/xfs_ialloc.h

index f51e38afdaabc1881e046838758b8376550e00cd..a2f1889982a0399f0e742763ff5ed08156fdf199 100644 (file)
@@ -61,20 +61,21 @@ typedef struct xfs_qoff_logitem {
 #define XFS_DEFER_OPS_NR_BUFS  2       /* join up to two buffers */
 
 typedef struct xfs_trans {
-       unsigned int    t_log_res;              /* amt of log space resvd */
-       unsigned int    t_log_count;            /* count for perm log res */
-       unsigned int    t_blk_res;              /* # of blocks resvd */
-       unsigned int    t_blk_res_used;         /* # of resvd blocks used */
-       unsigned int    t_rtx_res;              /* # of rt extents resvd */
-       unsigned int    t_rtx_res_used;         /* # of resvd rt extents used */
-       unsigned int    t_flags;                /* misc flags */
-       xfs_fsblock_t   t_firstblock;           /* first block allocated */
-       struct xfs_mount *t_mountp;             /* ptr to fs mount struct */
-       long            t_icount_delta;         /* superblock icount change */
-       long            t_ifree_delta;          /* superblock ifree change */
-       long            t_fdblocks_delta;       /* superblock fdblocks chg */
-       long            t_frextents_delta;      /* superblock freextents chg */
-       struct list_head        t_items;        /* first log item desc chunk */
+       unsigned int            t_log_res;      /* amt of log space resvd */
+       unsigned int            t_log_count;    /* count for perm log res */
+       unsigned int            t_blk_res;      /* # of blocks resvd */
+       unsigned int            t_blk_res_used; /* # of resvd blocks used */
+       unsigned int            t_rtx_res;      /* # of rt extents resvd */
+       unsigned int            t_rtx_res_used; /* # of resvd rt extents used */
+       unsigned int            t_flags;        /* misc flags */
+       xfs_fsblock_t           t_firstblock;   /* first block allocated */
+       struct xfs_mount        *t_mountp;      /* ptr to fs mount struct */
+       struct xfs_dquot_acct   *t_dqinfo;      /* acctg info for dquots */
+       long                    t_icount_delta; /* superblock icount change */
+       long                    t_ifree_delta;  /* superblock ifree change */
+       long                    t_fdblocks_delta;/* superblock fdblocks chg */
+       long                    t_frextents_delta;/* superblock freextents chg*/
+       struct list_head        t_items;        /* log item descriptors */
        struct list_head        t_dfops;        /* deferred operations */
 } xfs_trans_t;
 
index 376c5dac4cfbfae75dc71643fcdb2025dee96031..a79b650ae400e5df62a9915fae948d6eff466655 100644 (file)
@@ -560,16 +560,12 @@ libxfs_dir_ialloc(
        }
 
        if (ialloc_context) {
-
-               xfs_trans_bhold(tp, ialloc_context);
-
-               code = xfs_trans_roll(&tp);
+               code = xfs_dialloc_roll(&tp, ialloc_context);
                if (code) {
                        fprintf(stderr, _("%s: cannot duplicate transaction: %s\n"),
                                progname, strerror(code));
                        exit(1);
                }
-               xfs_trans_bjoin(tp, ialloc_context);
                code = libxfs_ialloc(tp, dp, mode, nlink, rdev, cr,
                                   fsx, &ialloc_context, &ip);
                if (!ip)
index 6b13f91dc30b0f31bf0ddb14c7ad69fd82ba8b24..fcd4529b686c51953a2c1b0b0cd68099ba810756 100644 (file)
@@ -1677,6 +1677,41 @@ error_cur:
        return error;
 }
 
+int
+xfs_dialloc_roll(
+       struct xfs_trans        **tpp,
+       struct xfs_buf          *agibp)
+{
+       struct xfs_trans        *tp = *tpp;
+       struct xfs_dquot_acct   *dqinfo;
+       int                     error;
+
+       /*
+        * Hold to on to the agibp across the commit so no other allocation can
+        * come in and take the free inodes we just allocated for our caller.
+        */
+       xfs_trans_bhold(tp, agibp);
+
+       /*
+        * 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 = tp->t_dqinfo;
+       tp->t_dqinfo = NULL;
+
+       error = xfs_trans_roll(&tp);
+
+       /* Re-attach the quota info that we detached from prev trx. */
+       tp->t_dqinfo = dqinfo;
+
+       *tpp = tp;
+       if (error)
+               return error;
+       xfs_trans_bjoin(tp, agibp);
+       return 0;
+}
+
 /*
  * Allocate an inode on disk.
  *
index 72b3468b97b152aeb364e2a933fbfe06fd7dee15..bd6e0db9e23cc5b87d9085cdb2f4eaf470f00447 100644 (file)
@@ -32,6 +32,11 @@ xfs_make_iptr(struct xfs_mount *mp, struct xfs_buf *b, int o)
        return xfs_buf_offset(b, o << (mp)->m_sb.sb_inodelog);
 }
 
+int
+xfs_dialloc_roll(
+       struct xfs_trans        **tpp,
+       struct xfs_buf          *agibp);
+
 /*
  * Allocate an inode on disk.
  * Mode is used to tell whether the new inode will need space, and whether