summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2022-07-14 11:16:18 -0700
committerDarrick J. Wong <djwong@kernel.org>2022-10-14 14:17:27 -0700
commit621d16dccbe0f464cd6b260366b8740adca96b82 (patch)
tree729bb9a74db9ae6730d897871f7004d16028d6f7
parenta111a1c44433c60d31a1de79ed5d60844a0038bd (diff)
xfs: fix rt growfs quota accounting
When growing the realtime bitmap or summary inodes, use xfs_trans_alloc_inode to reserve quota for the blocks that could be allocated to the file. Although we never enforce limits against the root dquot, making a reservation means that the bmap code will update the quota block count, which is necessary for correct accounting. Found by running xfs/521. Signed-off-by: Darrick J. Wong <djwong@kernel.org>
-rw-r--r--fs/xfs/xfs_rtalloc.c24
1 files changed, 8 insertions, 16 deletions
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 5e27cb7fce36..4165899cdc96 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -870,15 +870,10 @@ xfs_growfs_rt_alloc(
/*
* Reserve space & log for one extent added to the file.
*/
- error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtalloc, resblks,
- 0, 0, &tp);
+ error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_growrtalloc,
+ resblks, 0, false, &tp);
if (error)
return error;
- /*
- * Lock the inode.
- */
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK,
XFS_IEXT_ADD_NOSPLIT_CNT);
@@ -902,6 +897,7 @@ xfs_growfs_rt_alloc(
* Free any blocks freed up in the transaction, then commit.
*/
error = xfs_trans_commit(tp);
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
if (error)
return error;
/*
@@ -914,15 +910,11 @@ xfs_growfs_rt_alloc(
/*
* Reserve log for one block zeroing.
*/
- error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtzero,
- 0, 0, 0, &tp);
+ error = xfs_trans_alloc_inode(ip,
+ &M_RES(mp)->tr_growrtzero, 0, 0, false,
+ &tp);
if (error)
return error;
- /*
- * Lock the bitmap inode.
- */
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
error = xfs_growfs_init_rtbuf(tp, ip, fsbno, buf_type);
if (error)
@@ -932,6 +924,7 @@ xfs_growfs_rt_alloc(
* Commit the transaction.
*/
error = xfs_trans_commit(tp);
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
if (error)
return error;
}
@@ -945,6 +938,7 @@ xfs_growfs_rt_alloc(
out_trans_cancel:
xfs_trans_cancel(tp);
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
return error;
}
@@ -1310,8 +1304,6 @@ xfs_growfs_rt(
/* Unsupported realtime features. */
if (!xfs_has_rtgroups(mp) && (xfs_has_rmapbt(mp) || xfs_has_reflink(mp)))
return -EOPNOTSUPP;
- if (xfs_has_quota(mp))
- return -EOPNOTSUPP;
if (xfs_has_reflink(mp) && !is_power_of_2(mp->m_sb.sb_rextsize) &&
(XFS_FSB_TO_B(mp, mp->m_sb.sb_rextsize) & ~PAGE_MASK))
return -EOPNOTSUPP;