Commit 5575acc7807595687288b3bbac15103f2a5462e1

Authored by Kamal Dasu
Committed by Ben Myers
1 parent 1c2ccc66bc

xfs: fix deadlock in xfs_rtfree_extent

To fix the deadlock caused by repeatedly calling xfs_rtfree_extent

 - removed xfs_ilock() and xfs_trans_ijoin() from xfs_rtfree_extent(),
   instead added asserts that the inode is locked and has an inode_item
   attached to it.
 - in xfs_bunmapi() when dealing with an inode with the rt flag
   call xfs_ilock() and xfs_trans_ijoin() so that the
   reference count is bumped on the inode and attached it to the
   transaction before calling into xfs_bmap_del_extent, similar to
   what we do in xfs_bmap_rtalloc.

Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
Reviewed-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Ben Myers <bpm@sgi.com>

Showing 2 changed files with 13 additions and 5 deletions Side-by-side Diff

... ... @@ -5124,6 +5124,15 @@
5124 5124 cur->bc_private.b.flags = 0;
5125 5125 } else
5126 5126 cur = NULL;
  5127 +
  5128 + if (isrt) {
  5129 + /*
  5130 + * Synchronize by locking the bitmap inode.
  5131 + */
  5132 + xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL);
  5133 + xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL);
  5134 + }
  5135 +
5127 5136 extno = 0;
5128 5137 while (bno != (xfs_fileoff_t)-1 && bno >= start && lastx >= 0 &&
5129 5138 (nexts == 0 || extno < nexts)) {
fs/xfs/xfs_rtalloc.c
... ... @@ -183,6 +183,7 @@
183 183 oblocks = map.br_startoff + map.br_blockcount;
184 184 }
185 185 return 0;
  186 +
186 187 error:
187 188 return error;
188 189 }
... ... @@ -2139,11 +2140,9 @@
2139 2140 xfs_buf_t *sumbp; /* summary file block buffer */
2140 2141  
2141 2142 mp = tp->t_mountp;
2142   - /*
2143   - * Synchronize by locking the bitmap inode.
2144   - */
2145   - xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL);
2146   - xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL);
  2143 +
  2144 + ASSERT(mp->m_rbmip->i_itemp != NULL);
  2145 + ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
2147 2146  
2148 2147 #if defined(__KERNEL__) && defined(DEBUG)
2149 2148 /*