diff options
author | Jan Kara <jack@suse.cz> | 2007-09-11 18:23:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-09-11 20:21:19 -0400 |
commit | 9c3013e9b91ad23ecae88e45405e98208cce455d (patch) | |
tree | 2f18bb2d539727e2d9228a3d02a2e8810aa2ac3d /fs/ext3 | |
parent | af7b83f9324a77ef9a9080044bf0461f444ca651 (diff) |
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.c | 11 |
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) | |||
2578 | 2578 | ||
2579 | handle = ext3_journal_start(dquot_to_inode(dquot), | 2579 | handle = ext3_journal_start(dquot_to_inode(dquot), |
2580 | EXT3_QUOTA_DEL_BLOCKS(dquot->dq_sb)); | 2580 | EXT3_QUOTA_DEL_BLOCKS(dquot->dq_sb)); |
2581 | if (IS_ERR(handle)) | 2581 | if (IS_ERR(handle)) { |
2582 | /* Release dquot anyway to avoid endless cycle in dqput() */ | ||
2583 | dquot_release(dquot); | ||
2582 | return PTR_ERR(handle); | 2584 | return PTR_ERR(handle); |
2585 | } | ||
2583 | ret = dquot_release(dquot); | 2586 | ret = dquot_release(dquot); |
2584 | err = ext3_journal_stop(handle); | 2587 | err = ext3_journal_stop(handle); |
2585 | if (!ret) | 2588 | if (!ret) |
@@ -2712,6 +2715,12 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type, | |||
2712 | struct buffer_head *bh; | 2715 | struct buffer_head *bh; |
2713 | handle_t *handle = journal_current_handle(); | 2716 | handle_t *handle = journal_current_handle(); |
2714 | 2717 | ||
2718 | if (!handle) { | ||
2719 | printk(KERN_WARNING "EXT3-fs: Quota write (off=%Lu, len=%Lu)" | ||
2720 | " cancelled because transaction is not started.\n", | ||
2721 | (unsigned long long)off, (unsigned long long)len); | ||
2722 | return -EIO; | ||
2723 | } | ||
2715 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); | 2724 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); |
2716 | while (towrite > 0) { | 2725 | while (towrite > 0) { |
2717 | tocopy = sb->s_blocksize - offset < towrite ? | 2726 | tocopy = sb->s_blocksize - offset < towrite ? |