Skip to content

Commit 4c2c947

Browse files
djwonggregkh
authored andcommitted
xfs: fix reflink quota reservation accounting error
[ Upstream commit 8389522 ] Quota reservations are supposed to account for the blocks that might be allocated due to a bmap btree split. Reflink doesn't do this, so fix this to make the quota accounting more accurate before we start rearranging things. Fixes: 862bb36 ("xfs: reflink extents from one file to another") Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 17979d8 commit 4c2c947

1 file changed

Lines changed: 14 additions & 7 deletions

File tree

fs/xfs/xfs_reflink.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,7 @@ xfs_reflink_remap_extent(
10101010
xfs_filblks_t rlen;
10111011
xfs_filblks_t unmap_len;
10121012
xfs_off_t newlen;
1013+
int64_t qres;
10131014
int error;
10141015

10151016
unmap_len = irec->br_startoff + irec->br_blockcount - destoff;
@@ -1032,13 +1033,19 @@ xfs_reflink_remap_extent(
10321033
xfs_ilock(ip, XFS_ILOCK_EXCL);
10331034
xfs_trans_ijoin(tp, ip, 0);
10341035

1035-
/* If we're not just clearing space, then do we have enough quota? */
1036-
if (real_extent) {
1037-
error = xfs_trans_reserve_quota_nblks(tp, ip,
1038-
irec->br_blockcount, 0, XFS_QMOPT_RES_REGBLKS);
1039-
if (error)
1040-
goto out_cancel;
1041-
}
1036+
/*
1037+
* Reserve quota for this operation. We don't know if the first unmap
1038+
* in the dest file will cause a bmap btree split, so we always reserve
1039+
* at least enough blocks for that split. If the extent being mapped
1040+
* in is written, we need to reserve quota for that too.
1041+
*/
1042+
qres = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
1043+
if (real_extent)
1044+
qres += irec->br_blockcount;
1045+
error = xfs_trans_reserve_quota_nblks(tp, ip, qres, 0,
1046+
XFS_QMOPT_RES_REGBLKS);
1047+
if (error)
1048+
goto out_cancel;
10421049

10431050
trace_xfs_reflink_remap(ip, irec->br_startoff,
10441051
irec->br_blockcount, irec->br_startblock);

0 commit comments

Comments
 (0)