From: Andreas Gruenbacher - Fix transaction credit exhaustion BUG. - ext3_journal_get_write_access_credits failures break out of the loop in 1058, so is not released properly. - must be reset after journal_release_buffer() in line 1072. fs/ext3/xattr.c | 7 +++---- fs/jbd/transaction.c | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff -puN fs/ext3/xattr.c~ext3-xattr-fixes fs/ext3/xattr.c --- 25/fs/ext3/xattr.c~ext3-xattr-fixes 2003-07-12 13:07:16.000000000 -0700 +++ 25-akpm/fs/ext3/xattr.c 2003-07-12 13:08:25.000000000 -0700 @@ -1050,12 +1050,10 @@ ext3_xattr_cache_find(handle_t *handle, ext3_error(inode->i_sb, "ext3_xattr_cache_find", "inode %ld: block %ld read error", 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 * bh, which complicates things here. */ - if (ext3_journal_get_write_access_credits(handle, bh, - credits) != 0) - return NULL; lock_buffer(bh); if (le32_to_cpu(HDR(bh)->h_refcount) > EXT3_XATTR_REFCOUNT_MAX) { @@ -1070,6 +1068,7 @@ ext3_xattr_cache_find(handle_t *handle, } unlock_buffer(bh); journal_release_buffer(handle, bh, *credits); + *credits = 0; brelse(bh); } ce = mb_cache_entry_find_next(ce, 0, inode->i_sb->s_bdev, hash); diff -puN fs/jbd/transaction.c~ext3-xattr-fixes fs/jbd/transaction.c --- 25/fs/jbd/transaction.c~ext3-xattr-fixes 2003-07-12 13:07:16.000000000 -0700 +++ 25-akpm/fs/jbd/transaction.c 2003-07-12 13:07:33.000000000 -0700 @@ -742,7 +742,7 @@ int journal_get_write_access(handle_t *h /* We do not want to get caught playing with fields which the * log thread also manipulates. Make sure that the buffer * 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); return rc; } _