[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20130109201510.663378387@linuxfoundation.org>
Date: Wed, 9 Jan 2013 12:35:33 -0800
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org, stable@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
alan@...rguk.ukuu.org.uk, Dave Chinner <dchinner@...hat.com>,
Christoph Hellwig <hch@....de>, Ben Myers <bpm@....com>
Subject: [ 094/123] xfs: fix stray dquot unlock when reclaiming dquots
3.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Chinner <dchinner@...hat.com>
commit b870553cdecb26d5291af09602352b763e323df2 upstream.
When we fail to get a dquot lock during reclaim, we jump to an error
handler that unlocks the dquot. This is wrong as we didn't lock the
dquot, and unlocking it means who-ever is holding the lock has had
it silently taken away, and hence it results in a lock imbalance.
Found by inspection while modifying the code for the numa-lru
patchset. This fixes a random hang I've been seeing on xfstest 232
for the past several months.
Signed-off-by: Dave Chinner <dchinner@...hat.com>
Reviewed-by: Christoph Hellwig <hch@....de>
Signed-off-by: Ben Myers <bpm@....com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
fs/xfs/xfs_qm.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -1453,7 +1453,7 @@ xfs_qm_dqreclaim_one(
int error;
if (!xfs_dqlock_nowait(dqp))
- goto out_busy;
+ goto out_move_tail;
/*
* This dquot has acquired a reference in the meantime remove it from
@@ -1476,7 +1476,7 @@ xfs_qm_dqreclaim_one(
* getting flushed to disk, we don't want to reclaim it.
*/
if (!xfs_dqflock_nowait(dqp))
- goto out_busy;
+ goto out_unlock_move_tail;
if (XFS_DQ_IS_DIRTY(dqp)) {
struct xfs_buf *bp = NULL;
@@ -1487,7 +1487,7 @@ xfs_qm_dqreclaim_one(
if (error) {
xfs_warn(mp, "%s: dquot %p flush failed",
__func__, dqp);
- goto out_busy;
+ goto out_unlock_move_tail;
}
xfs_buf_delwri_queue(bp, buffer_list);
@@ -1496,7 +1496,7 @@ xfs_qm_dqreclaim_one(
* Give the dquot another try on the freelist, as the
* flushing will take some time.
*/
- goto out_busy;
+ goto out_unlock_move_tail;
}
xfs_dqfunlock(dqp);
@@ -1515,14 +1515,13 @@ xfs_qm_dqreclaim_one(
XFS_STATS_INC(xs_qm_dqreclaims);
return;
-out_busy:
- xfs_dqunlock(dqp);
-
/*
* Move the dquot to the tail of the list so that we don't spin on it.
*/
+out_unlock_move_tail:
+ xfs_dqunlock(dqp);
+out_move_tail:
list_move_tail(&dqp->q_lru, &qi->qi_lru_list);
-
trace_xfs_dqreclaim_busy(dqp);
XFS_STATS_INC(xs_qm_dqreclaim_misses);
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists