aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKamal Dasu <kdasu.kdev@gmail.com>2012-02-22 19:41:39 -0500
committerBen Myers <bpm@sgi.com>2012-03-22 16:31:06 -0400
commit5575acc7807595687288b3bbac15103f2a5462e1 (patch)
tree1a47a34756e1c0023e2df8f3b1d9e10de568601a
parent1c2ccc66bcef992bec7bad6d52cade66d632d7fb (diff)
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>
-rw-r--r--fs/xfs/xfs_bmap.c9
-rw-r--r--fs/xfs/xfs_rtalloc.c9
2 files changed, 13 insertions, 5 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 3548c6f7559..85e7e327bcd 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -5124,6 +5124,15 @@ xfs_bunmapi(
5124 cur->bc_private.b.flags = 0; 5124 cur->bc_private.b.flags = 0;
5125 } else 5125 } else
5126 cur = NULL; 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 extno = 0; 5136 extno = 0;
5128 while (bno != (xfs_fileoff_t)-1 && bno >= start && lastx >= 0 && 5137 while (bno != (xfs_fileoff_t)-1 && bno >= start && lastx >= 0 &&
5129 (nexts == 0 || extno < nexts)) { 5138 (nexts == 0 || extno < nexts)) {
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 87323f1ded6..ca4f31534a0 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -183,6 +183,7 @@ error_cancel:
183 oblocks = map.br_startoff + map.br_blockcount; 183 oblocks = map.br_startoff + map.br_blockcount;
184 } 184 }
185 return 0; 185 return 0;
186
186error: 187error:
187 return error; 188 return error;
188} 189}
@@ -2139,11 +2140,9 @@ xfs_rtfree_extent(
2139 xfs_buf_t *sumbp; /* summary file block buffer */ 2140 xfs_buf_t *sumbp; /* summary file block buffer */
2140 2141
2141 mp = tp->t_mountp; 2142 mp = tp->t_mountp;
2142 /* 2143
2143 * Synchronize by locking the bitmap inode. 2144 ASSERT(mp->m_rbmip->i_itemp != NULL);
2144 */ 2145 ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
2145 xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL);
2146 xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL);
2147 2146
2148#if defined(__KERNEL__) && defined(DEBUG) 2147#if defined(__KERNEL__) && defined(DEBUG)
2149 /* 2148 /*