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) { /*