summary refs log tree commit diff
path: root/fs/ext3
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2007-09-11 15:23:29 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-09-11 17:21:19 -0700
commit9c3013e9b91ad23ecae88e45405e98208cce455d (patch)
tree2f18bb2d539727e2d9228a3d02a2e8810aa2ac3d /fs/ext3
parentaf7b83f9324a77ef9a9080044bf0461f444ca651 (diff)
downloadlinux-9c3013e9b91ad23ecae88e45405e98208cce455d.tar.gz
quota: fix infinite loop
If we fail to start a transaction when releasing dquot, we have to call
dquot_release() anyway to mark dquot structure as inactive.  Otherwise we
end in an infinite loop inside dqput().

Signed-off-by: Jan Kara <jack@suse.cz>
Cc: xb <xavier.bru@bull.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ext3')
-rw-r--r--fs/ext3/super.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 22cfdd61c060..9537316a0714 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -2578,8 +2578,11 @@ static int ext3_release_dquot(struct dquot *dquot)
 
 	handle = ext3_journal_start(dquot_to_inode(dquot),
 					EXT3_QUOTA_DEL_BLOCKS(dquot->dq_sb));
-	if (IS_ERR(handle))
+	if (IS_ERR(handle)) {
+		/* Release dquot anyway to avoid endless cycle in dqput() */
+		dquot_release(dquot);
 		return PTR_ERR(handle);
+	}
 	ret = dquot_release(dquot);
 	err = ext3_journal_stop(handle);
 	if (!ret)
@@ -2712,6 +2715,12 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type,
 	struct buffer_head *bh;
 	handle_t *handle = journal_current_handle();
 
+	if (!handle) {
+		printk(KERN_WARNING "EXT3-fs: Quota write (off=%Lu, len=%Lu)"
+			" cancelled because transaction is not started.\n",
+			(unsigned long long)off, (unsigned long long)len);
+		return -EIO;
+	}
 	mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
 	while (towrite > 0) {
 		tocopy = sb->s_blocksize - offset < towrite ?