Patchwork [3.5.y.z,extended,stable] Patch "xfs: fix stray dquot unlock when reclaiming dquots" has been added to staging queue

mail settings
Submitter Herton Ronaldo Krzesinski
Date Jan. 7, 2013, 8:35 p.m.
Message ID <>
Download mbox | patch
Permalink /patch/210173/
State New
Headers show


Herton Ronaldo Krzesinski - Jan. 7, 2013, 8:35 p.m.
This is a note to let you know that I have just added a patch titled

    xfs: fix stray dquot unlock when reclaiming dquots

to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree 
which can be found at:;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.y.z tree, see



From 5ff4894eb72f5aa70ab0ed4de1c45296335da955 Mon Sep 17 00:00:00 2001
From: Dave Chinner <>
Date: Wed, 28 Nov 2012 13:01:02 +1100
Subject: [PATCH] xfs: fix stray dquot unlock when reclaiming dquots

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 <>
Reviewed-by: Christoph Hellwig <>
Signed-off-by: Ben Myers <>
Signed-off-by: Herton Ronaldo Krzesinski <>
 fs/xfs/xfs_qm.c |   15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)



diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 249db19..92eb490 100644
--- 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;

@@ -1515,14 +1515,13 @@  xfs_qm_dqreclaim_one(

-	xfs_dqunlock(dqp);
 	 * Move the dquot to the tail of the list so that we don't spin on it.
+	xfs_dqunlock(dqp);
 	list_move_tail(&dqp->q_lru, &qi->qi_lru_list);