]> www.infradead.org Git - users/hch/xfs.git/commitdiff
xfs: refactor reflink quota updates
authorDarrick J. Wong <djwong@kernel.org>
Tue, 15 Oct 2024 19:40:25 +0000 (12:40 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 5 Nov 2024 21:36:31 +0000 (13:36 -0800)
Hoist all quota updates for reflink into a helper function, since things
are about to become more complicated.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
fs/xfs/xfs_reflink.c

index 66ce29101462cde0399b30dbc73657b73e7c49d9..29574b015fddc078c33407ba9658310ab1f97602 100644 (file)
@@ -739,6 +739,35 @@ out:
        return error;
 }
 
+#ifdef CONFIG_XFS_QUOTA
+/*
+ * Update quota accounting for a remapping operation.  When we're remapping
+ * something from the CoW fork to the data fork, we must update the quota
+ * accounting for delayed allocations.  For remapping from the data fork to the
+ * data fork, use regular block accounting.
+ */
+static inline void
+xfs_reflink_update_quota(
+       struct xfs_trans        *tp,
+       struct xfs_inode        *ip,
+       bool                    is_cow,
+       int64_t                 blocks)
+{
+       unsigned int            qflag;
+
+       if (XFS_IS_REALTIME_INODE(ip)) {
+               qflag = is_cow ? XFS_TRANS_DQ_DELRTBCOUNT :
+                                XFS_TRANS_DQ_RTBCOUNT;
+       } else {
+               qflag = is_cow ? XFS_TRANS_DQ_DELBCOUNT :
+                                XFS_TRANS_DQ_BCOUNT;
+       }
+       xfs_trans_mod_dquot_byino(tp, ip, qflag, blocks);
+}
+#else
+# define xfs_reflink_update_quota(tp, ip, is_cow, blocks)      ((void)0)
+#endif
+
 /*
  * Remap part of the CoW fork into the data fork.
  *
@@ -833,8 +862,7 @@ xfs_reflink_end_cow_extent(
                 */
                xfs_bmap_unmap_extent(tp, ip, XFS_DATA_FORK, &data);
                xfs_refcount_decrease_extent(tp, isrt, &data);
-               xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT,
-                               -data.br_blockcount);
+               xfs_reflink_update_quota(tp, ip, false, -data.br_blockcount);
        } else if (data.br_startblock == DELAYSTARTBLOCK) {
                int             done;
 
@@ -859,8 +887,7 @@ xfs_reflink_end_cow_extent(
        xfs_bmap_map_extent(tp, ip, XFS_DATA_FORK, &del);
 
        /* Charge this new data fork mapping to the on-disk quota. */
-       xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_DELBCOUNT,
-                       (long)del.br_blockcount);
+       xfs_reflink_update_quota(tp, ip, true, del.br_blockcount);
 
        /* Remove the mapping from the CoW fork. */
        xfs_bmap_del_extent_cow(ip, &icur, &got, &del);
@@ -1347,7 +1374,7 @@ xfs_reflink_remap_extent(
                qdelta += dmap->br_blockcount;
        }
 
-       xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, qdelta);
+       xfs_reflink_update_quota(tp, ip, false, qdelta);
 
        /* Update dest isize if needed. */
        newlen = XFS_FSB_TO_B(mp, dmap->br_startoff + dmap->br_blockcount);