Sophie

Sophie

distrib > CentOS > 5 > x86_64 > by-pkgid > ea32411352494358b8d75a78402a4713 > files > 1199

kernel-2.6.18-238.19.1.el5.centos.plus.src.rpm

From: Eric Sandeen <sandeen@redhat.com>
Date: Tue, 30 Mar 2010 17:12:30 -0400
Subject: [fs] quota: fix possible infinite loop in quota code
Message-id: <4BB230FE.6070604@redhat.com>
Patchwork-id: 23828
O-Subject: [PATCH RHEL5.6] quota: fix possible infinite loop in quota code
Bugzilla: 546060
RH-Acked-by: Jerome Marchand <jmarchan@redhat.com>

This is for
Bug 546060 - soft lockup while unmounting a read-only filesystem with errors

and it's a straightforward application of the following upstream
patch.

Tested with the reproducer contained in the bug.

Thanks,
-Eric

From: Jan Kara <jack@suse.cz>
Date: Fri, 25 Jul 2008 08:46:49 +0000 (-0700)
Subject: quota: fix possible infinite loop in quota code
X-Git-Tag: v2.6.27-rc1~401

quota: fix possible infinite loop in quota code

When quota structure is going to be dropped and it is dirty, quota code tries
to write it.  If the write fails for some reason (e.  g.  transaction cannot
be started because the journal is aborted), we try writing again and again and
again...  Fix the problem by clearing the dirty bit even if the write failed.

(akpm: for 2.6.27, 2.6.26.x and 2.6.25.x)

Signed-off-by: Jan Kara <jack@suse.cz>
Reviewed-by: dingdinghua <dingdinghua85@gmail.com>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

diff --git a/fs/dquot.c b/fs/dquot.c
index 9af7895..f80c14a 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -545,6 +545,8 @@ static int shrink_dqcache_memory(int nr, gfp_t gfp_mask)
  */
 static void dqput(struct dquot *dquot)
 {
+	int ret;
+
 	if (!dquot)
 		return;
 #ifdef __DQUOT_PARANOIA
@@ -577,7 +579,19 @@ we_slept:
 	if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && dquot_dirty(dquot)) {
 		spin_unlock(&dq_list_lock);
 		/* Commit dquot before releasing */
-		dquot->dq_sb->dq_op->write_dquot(dquot);
+		ret = dquot->dq_sb->dq_op->write_dquot(dquot);
+		if (ret < 0) {
+			printk(KERN_ERR "VFS: cannot write quota structure on "
+				"device %s (error %d). Quota may get out of "
+				"sync!\n", dquot->dq_sb->s_id, ret);
+			/*
+			 * We clear dirty bit anyway, so that we avoid
+			 * infinite loop here
+			 */
+			spin_lock(&dq_list_lock);
+			clear_dquot_dirty(dquot);
+			spin_unlock(&dq_list_lock);
+		}
 		goto we_slept;
 	}
 	/* Clear flag in case dquot was inactive (something bad happened) */