Commit 2e1972fa authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ext3 extended attribute fixes

From: Andreas Gruenbacher <agruen@suse.de>

- Fix transaction credit exhaustion BUG.

- ext3_journal_get_write_access_credits failures break out of the loop in
  1058, so <ce> is not released properly.

- <credits> must be reset after journal_release_buffer() in line 1072.
parent 7360a440
...@@ -1050,12 +1050,10 @@ ext3_xattr_cache_find(handle_t *handle, struct inode *inode, ...@@ -1050,12 +1050,10 @@ ext3_xattr_cache_find(handle_t *handle, struct inode *inode,
ext3_error(inode->i_sb, "ext3_xattr_cache_find", ext3_error(inode->i_sb, "ext3_xattr_cache_find",
"inode %ld: block %ld read error", "inode %ld: block %ld read error",
inode->i_ino, (unsigned long) ce->e_block); inode->i_ino, (unsigned long) ce->e_block);
} else { } else if (ext3_journal_get_write_access_credits(
handle, bh, credits) == 0) {
/* ext3_journal_get_write_access() requires an unlocked /* ext3_journal_get_write_access() requires an unlocked
* bh, which complicates things here. */ * bh, which complicates things here. */
if (ext3_journal_get_write_access_credits(handle, bh,
credits) != 0)
return NULL;
lock_buffer(bh); lock_buffer(bh);
if (le32_to_cpu(HDR(bh)->h_refcount) > if (le32_to_cpu(HDR(bh)->h_refcount) >
EXT3_XATTR_REFCOUNT_MAX) { EXT3_XATTR_REFCOUNT_MAX) {
...@@ -1070,6 +1068,7 @@ ext3_xattr_cache_find(handle_t *handle, struct inode *inode, ...@@ -1070,6 +1068,7 @@ ext3_xattr_cache_find(handle_t *handle, struct inode *inode,
} }
unlock_buffer(bh); unlock_buffer(bh);
journal_release_buffer(handle, bh, *credits); journal_release_buffer(handle, bh, *credits);
*credits = 0;
brelse(bh); brelse(bh);
} }
ce = mb_cache_entry_find_next(ce, 0, inode->i_sb->s_bdev, hash); ce = mb_cache_entry_find_next(ce, 0, inode->i_sb->s_bdev, hash);
......
...@@ -742,7 +742,7 @@ int journal_get_write_access(handle_t *handle, ...@@ -742,7 +742,7 @@ int journal_get_write_access(handle_t *handle,
/* We do not want to get caught playing with fields which the /* We do not want to get caught playing with fields which the
* log thread also manipulates. Make sure that the buffer * log thread also manipulates. Make sure that the buffer
* completes any outstanding IO before proceeding. */ * completes any outstanding IO before proceeding. */
rc = do_get_write_access(handle, jh, 0, NULL); rc = do_get_write_access(handle, jh, 0, credits);
journal_put_journal_head(jh); journal_put_journal_head(jh);
return rc; return rc;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment