diff options
author | Darrick J. Wong <djwong@kernel.org> | 2021-02-01 11:42:52 -0800 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2021-03-25 17:08:53 -0700 |
commit | eada055b4803d15380e62b0b1296f4a7599c8bde (patch) | |
tree | 4cacd358b29e2c4d062f1a6d5ff76dbf73d30757 | |
parent | a251bf581d7ae7b24a1e5ffc5bca49cb71e71ff6 (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.c | 24 |
1 files changed, 10 insertions, 14 deletions
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index a4ee08e5d734..4818474014c6 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -29,6 +29,7 @@ #include "xfs_quota.h" #include "xfs_rtrmap_btree.h" #include "xfs_rtrefcount_btree.h" +#include "xfs_quota.h" /* * Read and return the summary information for a given extent size, @@ -804,15 +805,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); @@ -833,6 +829,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; /* @@ -845,15 +842,12 @@ 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); + /* * Get a buffer for the block. */ @@ -871,6 +865,7 @@ xfs_growfs_rt_alloc( * Commit the transaction. */ error = xfs_trans_commit(tp); + xfs_iunlock(ip, XFS_ILOCK_EXCL); if (error) return error; } @@ -884,6 +879,7 @@ xfs_growfs_rt_alloc( out_trans_cancel: xfs_trans_cancel(tp); + xfs_iunlock(ip, XFS_ILOCK_EXCL); return error; } |