xfs: refactor reflink quota updates

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>
Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
Darrick J. Wong 2024-11-20 16:20:58 -08:00
parent c2694ff678
commit 3639c63d46

View File

@ -739,6 +739,35 @@ xfs_reflink_cancel_cow_range(
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);