summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_reflink.c
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2020-06-29 14:47:19 -0700
committerDarrick J. Wong <darrick.wong@oracle.com>2020-07-06 10:46:57 -0700
commitaa5d0ba0b5dbb5105276214c7f9124855b20f75e (patch)
treee445d2cc344d8f4d0526d5cf229fc23cd9c035c0 /fs/xfs/xfs_reflink.c
parent00fd1d56dd08a8ceaa9e4ee1a41fefd9f6c6bc7d (diff)
xfs: only reserve quota blocks for bmbt changes if we're changing the data fork
Now that we've reworked xfs_reflink_remap_extent to remap only one extent per transaction, we actually know if the extent being removed is an allocated mapping. This means that we now know ahead of time if we're going to be touching the data fork. Since we only need blocks for a bmbt split if we're going to update the data fork, we only need to get quota reservation if we know we're going to touch the data fork. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Brian Foster <bfoster@redhat.com>
Diffstat (limited to 'fs/xfs/xfs_reflink.c')
-rw-r--r--fs/xfs/xfs_reflink.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index e7dd8950d40a..3073c608216c 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -1047,7 +1047,11 @@ xfs_reflink_remap_extent(
* Compute quota reservation if we think the quota block counter for
* this file could increase.
*
- * We start by reserving enough blocks to handle a bmbt split.
+ * Adding a written extent to the extent map can cause a bmbt split,
+ * and removing a mapped extent from the extent can cause a bmbt split.
+ * The two operations cannot both cause a split since they operate on
+ * the same index in the bmap btree, so we only need a reservation for
+ * one bmbt split if either thing is happening.
*
* If we are mapping a written extent into the file, we need to have
* enough quota block count reservation to handle the blocks in that
@@ -1060,14 +1064,17 @@ xfs_reflink_remap_extent(
* before we started. That should have removed all the delalloc
* reservations, but we code defensively.
*/
- qdelta = 0;
- qres = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
+ qres = qdelta = 0;
+ if (smap_real || dmap_written)
+ qres = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
if (dmap_written)
qres += dmap->br_blockcount;
- error = xfs_trans_reserve_quota_nblks(tp, ip, qres, 0,
- XFS_QMOPT_RES_REGBLKS);
- if (error)
- goto out_cancel;
+ if (qres > 0) {
+ error = xfs_trans_reserve_quota_nblks(tp, ip, qres, 0,
+ XFS_QMOPT_RES_REGBLKS);
+ if (error)
+ goto out_cancel;
+ }
if (smap_real) {
/*