[PATCH V7 13/17] xfs: xfs_growfs_rt_alloc: Unlock inode explicitly rather than through iop_committing()

Chandan Babu R
2022-03-01T10:40:44Z

In order to be able to upgrade inodes to XFS_DIFLAG2_NREXT64, a future commit
will perform such an upgrade in a transaction context. This requires the
transaction to be rolled once. Hence inodes which have been added to the
tranasction (via xfs_trans_ijoin()) with non-zero value for lock_flags
argument would cause the inode to be unlocked when the transaction is rolled.

To prevent this from happening in the case of realtime bitmap/summary inodes,
this commit now unlocks the inode explictly rather than through
iop_committing() call back.

Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
fs/xfs/xfs_rtalloc.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index b8c79ee791af..a70140b35e8b 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -780,6 +780,7 @@ xfs_growfs_rt_alloc(
int resblks; /* space reservation */
enum xfs_blft buf_type;
struct xfs_trans *tp;
+ bool unlock_inode;

if (ip == mp->m_rsumip)
buf_type = XFS_BLFT_RTSUMMARY_BUF;
@@ -802,7 +803,8 @@ xfs_growfs_rt_alloc(
* Lock the inode.
*/
xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
+ xfs_trans_ijoin(tp, ip, 0);
+ unlock_inode = true;

error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK,
XFS_IEXT_ADD_NOSPLIT_CNT);
@@ -823,8 +825,11 @@ xfs_growfs_rt_alloc(
* Free any blocks freed up in the transaction, then commit.
*/
error = xfs_trans_commit(tp);
- if (error)
+ unlock_inode = false;
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ if (error)
return error;
+
/*
* Now we need to clear the allocated blocks.
* Do this one block per transaction, to keep it simple.
@@ -874,6 +879,8 @@ xfs_growfs_rt_alloc(

out_trans_cancel:
xfs_trans_cancel(tp);
+ if (unlock_inode)
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
return error;
}

--
2.30.2