summaryrefslogtreecommitdiff
path: root/fs/reiserfs/super.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2007-09-12 02:23:29 +0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-09-12 04:21:19 +0400
commit9c3013e9b91ad23ecae88e45405e98208cce455d (patch)
tree2f18bb2d539727e2d9228a3d02a2e8810aa2ac3d /fs/reiserfs/super.c
parentaf7b83f9324a77ef9a9080044bf0461f444ca651 (diff)
downloadlinux-9c3013e9b91ad23ecae88e45405e98208cce455d.tar.xz
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/reiserfs/super.c')
-rw-r--r--fs/reiserfs/super.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 5b68dd3f191a..a005451930b7 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1915,8 +1915,11 @@ static int reiserfs_release_dquot(struct dquot *dquot)
ret =
journal_begin(&th, dquot->dq_sb,
REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
- if (ret)
+ if (ret) {
+ /* Release dquot anyway to avoid endless cycle in dqput() */
+ dquot_release(dquot);
goto out;
+ }
ret = dquot_release(dquot);
err =
journal_end(&th, dquot->dq_sb,
@@ -2067,6 +2070,12 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
size_t towrite = len;
struct buffer_head tmp_bh, *bh;
+ if (!current->journal_info) {
+ printk(KERN_WARNING "reiserfs: 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 ?
@@ -2098,7 +2107,7 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
data += tocopy;
blk++;
}
- out:
+out:
if (len == towrite)
return err;
if (inode->i_size < off + len - towrite)