From: Darrick J. Wong <djwong@xxxxxxxxxx> 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@xxxxxxxxxx> --- fs/xfs/xfs_rtalloc.c | 24 ++++++++---------------- 1 file 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;