xfs: treat CoW fork operations as delalloc for quota accounting
Since the CoW fork only exists in memory, it is incorrect to update the on-disk quota block counts when we modify the CoW fork. Unlike the data fork, even real extents in the CoW fork are only delalloc-style reservations (on-disk they're owned by the refcountbt) so they must not be tracked in the on disk quota info. Ensure the i_delayed_blks accounting reflects this too. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
@@ -599,10 +599,6 @@ xfs_reflink_cancel_cow_blocks(
|
||||
del.br_startblock, del.br_blockcount,
|
||||
NULL);
|
||||
|
||||
/* Update quota accounting */
|
||||
xfs_trans_mod_dquot_byino(*tpp, ip, XFS_TRANS_DQ_BCOUNT,
|
||||
-(long)del.br_blockcount);
|
||||
|
||||
/* Roll the transaction */
|
||||
xfs_defer_ijoin(&dfops, ip);
|
||||
error = xfs_defer_finish(tpp, &dfops);
|
||||
@@ -613,6 +609,13 @@ xfs_reflink_cancel_cow_blocks(
|
||||
|
||||
/* Remove the mapping from the CoW fork. */
|
||||
xfs_bmap_del_extent_cow(ip, &icur, &got, &del);
|
||||
|
||||
/* Remove the quota reservation */
|
||||
error = xfs_trans_reserve_quota_nblks(NULL, ip,
|
||||
-(long)del.br_blockcount, 0,
|
||||
XFS_QMOPT_RES_REGBLKS);
|
||||
if (error)
|
||||
break;
|
||||
} else {
|
||||
/* Didn't do anything, push cursor back. */
|
||||
xfs_iext_prev(ifp, &icur);
|
||||
@@ -795,6 +798,10 @@ xfs_reflink_end_cow(
|
||||
if (error)
|
||||
goto out_defer;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Remove the mapping from the CoW fork. */
|
||||
xfs_bmap_del_extent_cow(ip, &icur, &got, &del);
|
||||
|
||||
|
Reference in New Issue
Block a user